views:

3869

answers:

4

I am looking for a way to use a UILabel (or something similar) to display something like this:

Tom: Some message.

It is like how it's done in for example the Facebook app to display the "what's on your mind?" messages. Does anyone have any suggestions how to approach this?

+1  A: 

Why do you even need one UILabel, as far as I know you can make it a view and add as many UILabel's to it as you want

phunehehe
+3  A: 

Use two UILabel IBOutlets, each with a different format (font/color/etc), as you desire.. Move the second one over the first based on where the first one's text ends. You can get that via sizeWithFont:forWidth:lineBreakMode:

Alternatively, you can subclass UILabel, and draw the text yourself in drawRect. If you do it this way, just add an instance variable to tell you how much of the string to draw in one format, and draw the rest in another.

mahboudz
Or, to be more complicated than is probably necessary, build your own HTML to represent the message and display it in a UIWebView.
Tyler
Ok, I was hoping for a more elegant solution. But apparently I just have to do it manually. Thank you!
Tom van Zummeren
+2  A: 

You can use the same tools that the facebook app uses: three20

Joe Hewitt, the developer behind the facebook app has open sourced much of his work. You can get it and many other goodies here: http://github.com/joehewitt/three20

coneybeare
+6  A: 

I created this basic UIView subclass to support similar functionality.

The list of things it doesn't support is longer than what it does, but basically it allows you to manage a single line of UILabels and format each as you want. This lets me interject text with a different color in the middle of the line, for instance, and avoid using the heavy-weight UIWebView.

I create these objects by placing a UIView object in my interface (using Interface Builder) and setting the type of the object in IB to MultipartLabel. Then in the code I call updateNumberOfLabels and the various setText selectors as needed.

//  MultipartLabel.m
//  MultiLabelLabel
//
//  Created by Jason Miller on 10/7/09.
//  Copyright 2009 Jason Miller. All rights reserved.
//

#import "MultipartLabel.h"

@interface MultipartLabel (Private)
- (void)updateLayout;
@end

@implementation MultipartLabel

@synthesize containerView;
@synthesize labels;

-(void)updateNumberOfLabels:(int)numLabels;
{
 [containerView removeFromSuperview];
 self.containerView = nil;

 self.containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)] autorelease];
 [self addSubview:self.containerView];
 self.labels = [NSMutableArray array];

 while (numLabels-- > 0) {
  UILabel * label = [[UILabel alloc] initWithFrame:CGRectZero];
  [self.containerView addSubview:label];
  [self.labels addObject:label];
  [label release];
 }

 [self updateLayout];
}

-(void)setText:(NSString *)text forLabel:(int)labelNum;
{
 if( [self.labels count] > labelNum && labelNum >= 0 )
 {
  UILabel * thisLabel = [self.labels objectAtIndex:labelNum];
  thisLabel.text = text;
 }

 [self updateLayout];
}

-(void)setText:(NSString *)text andFont:(UIFont*)font forLabel:(int)labelNum;
{
 if( [self.labels count] > labelNum && labelNum >= 0 )
 {
  UILabel * thisLabel = [self.labels objectAtIndex:labelNum];
  thisLabel.text = text;
  thisLabel.font = font;
 }

 [self updateLayout];
}

-(void)setText:(NSString *)text andColor:(UIColor*)color forLabel:(int)labelNum;
{
 if( [self.labels count] > labelNum && labelNum >= 0 )
 {
  UILabel * thisLabel = [self.labels objectAtIndex:labelNum];
  thisLabel.text = text;
  thisLabel.textColor = color;
 }

 [self updateLayout];
}

-(void)setText:(NSString *)text andFont:(UIFont*)font andColor:(UIColor*)color forLabel:(int)labelNum;
{
 if( [self.labels count] > labelNum && labelNum >= 0 )
 {
  UILabel * thisLabel = [self.labels objectAtIndex:labelNum];
  thisLabel.text = text;
  thisLabel.font = font;
  thisLabel.textColor = color;
 }

 [self updateLayout];
}

- (void)updateLayout {

 int thisX = 0;

 // TODO when it is time to support different sized fonts, need to adjust each y value to line up baselines

 for (UILabel * thisLabel in self.labels) {
  CGSize size = [thisLabel.text sizeWithFont:thisLabel.font
         constrainedToSize:CGSizeMake(9999, 9999)
          lineBreakMode:thisLabel.lineBreakMode];
  CGRect thisFrame = CGRectMake( thisX, 0, size.width, size.height );
  thisLabel.frame = thisFrame;

  thisX += size.width;
 }
}


- (void)dealloc {
 [labels release];
 labels = nil;

 [containerView release];
 containerView = nil;

    [super dealloc];
}


@end
Jason
You rock! Nicely done.
JBRWilkinson
can't get this working. is there a working project file?
cannyboy
Sorry, that's all I've got!
Jason