I'm making a chat application. When a message arrives then it has to say who sent it. For example, if I were the sender then it should say
Takeshi: message
Andres: message
I want "Takeshi" and "Andres" to be of a different color but on the same line with the message, with line wrapping, like this:
Takeshi: some message text, text, text , text
text, text, text end.
I am trying the following:
Calculate the size of the message.
Calculate the size of the sender's name.
Create string of " " with the length of the sender's name.
but " " not is not sufficient.
I make this:
NSString *from;
if(usr){
from = [NSString stringWithFormat:#"%#: ", #"Yo"];
}else{
from = [NSString stringWithFormat:#"%#: ", [_lbSupportName text]];
}
//This give me one string of n characters of ' ' character.
NSString *spaces = [ChatView stringWithRepeatCharacter:' ' times:from.length * 2];
NSString *mensaje = [NSString stringWithFormat:#"%# %#", spaces, msg];
//Calculating the height
CGSize messageSize = [mensaje sizeWithFont:[UIFont fontWithName:DEFAULT_TEXTFONT size:20]
constrainedToSize:CGSizeMake(_scvConversation.frame.size.width - 10, FLT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
CGSize fromSize = [from sizeWithFont:[UIFont fontWithName:DEFAULT_TEXTFONT size:22]
constrainedToSize:CGSizeMake(FLT_MAX, FLT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
//Image Background
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(5, yConversationPosition + 5, _scvConversation.frame.size.width - 10, messageSize.height + 30)];
yConversationPosition += image.frame.size.height + 5;
//Create the Label From
UILabel *lb_From = [[UILabel alloc] initWithFrame:CGRectMake(0, 9, fromSize.width, 30)];
[lb_From setFont:[UIFont fontWithName:DEFAULT_TEXTFONT size:20]];
[lb_From setBackgroundColor:[UIColor clearColor]];
[lb_From setText:from];
//Create the Label Message
UILabel *lb_WriteMessage = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, image.frame.size.width-10, image.frame.size.height - 10)];
[lb_WriteMessage setNumberOfLines:messageSize.height / DEFAULT_TEXTSIZE];
[lb_WriteMessage setFont:[UIFont fontWithName:DEFAULT_TEXTFONT size:20]];
[lb_WriteMessage setText:mensaje];
[lb_WriteMessage setBackgroundColor:[UIColor clearColor]];
[lb_WriteMessage setTextColor:[UIColor colorWithRed:(92/255.0f) green:(98/255.0f) blue:(101/255.0f) alpha:1]];
if(usr){
[image setImage:[UIImage imageNamed:#"chat-mensajes-yo.png"]];
[lb_From setTextColor:[UIColor colorWithRed:(230/255.0f) green:(85/255.0f) blue:(84/255.0f) alpha:1]];
}else{
[image setImage:[UIImage imageNamed:#"chat-mensajes-asesor.png"]];
[lb_From setTextColor:[UIColor colorWithRed:(28/255.0f) green:(168/255.0f) blue:(175/255.0f) alpha:1]];
}
[lb_WriteMessage addSubview:lb_From];
[image addSubview:lb_WriteMessage];
[_scvConversation addSubview:image];
//Set the contentSize of the scv_Message and scroll to the new Message
[_scvConversation setContentSize:CGSizeMake(0, yConversationPosition)];
if(_scvConversation.contentSize.height > _scvConversation.frame.size.height){
//Scroll to last Message
float diference = yConversationPosition - _scvConversation.frame.size.height +5;
[_scvConversation setContentOffset:CGPointMake(0, diference)];
}
[image release];
[lb_WriteMessage release];
Please help, I could not do that. :/
You should use two labels. Create the first label for "Name:" with the color you want (1 line label) and calcuate its width based on the text, then create a new label and calculate its height and number of lines and position it using:
[lb_WriteMessage setFrame:CGRectMake(lb_From.frame.origin.x + lb_From.frame.size.width + spacer, lb_from.origin.y, messageSize.width, messageSize.height)];
(where spacer is the number of pixels space you want between the labels).
Take a look on Core Text API. It's not a simple tool, but it gives you incredible flexibility when you understand how it works.
Here is a good start point: http://www.cocoanetics.com/2011/01/befriending-core-text/
Probably later you will want to use more complicated logic in your chat like names highlighting in messages, or some other rich text formating. You can do all this with core text.
Related
I just want to highlight only text in UILabel, I have tried by giving backgroundColor for label, but it is highlighting the empty spaces also looks not good. So Is there any way to highlight text without resizing UILabel.
Please check the image, here labels are bigger than the text (center aligned)
Thanx.
Most of the other solutions don't consider text that spans multiple lines while still only highlighting the text, and they are all pretty hacky involving extra subviews.
An iOS 6 and later solution is to use attributed strings:
NSMutableAttributedString *s =
[[NSMutableAttributedString alloc] initWithString:yourString];
[s addAttribute:NSBackgroundColorAttributeName
value:[UIColor greenColor]
range:NSMakeRange(0, s.length)];
label.attributedText = s;
This will add a subview behind the text, with the correct size:
CGSize size= [[label text] sizeWithFont:[UIFont systemFontOfSize:18.0]];
NSLog(#"%.1f | %.1f", size.width, size.height);
NSLog(#"%.1f | %.1f", label.frame.size.width, label.frame.size.height);
UIView *highlightView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
[highlightView setBackgroundColor:[UIColor greenColor]];
[self.view insertSubview:highlightView belowSubview:label];
[highlightView setCenter:label.center];
And don't forget: [label setBackgroundColor:[UIColor clearColor]];
try this
MTLabel
MTLabel *label4 = [MTLabel labelWithFrame:CGRectMake(20, 270, 250, 60)
andText:#"This label is highlighted, has a custom line height, and adjusts font size to fit inside the label."];
[label4 setLineHeight:22];
[label4 setFont:[UIFont fontWithName:#"Helvetica" size:30]];
[label4 setAdjustSizeToFit:YES];
[label4 setMinimumFontSize:15];
[label4 setFontHighlightColor:[[UIColor orangeColor] colorWithAlphaComponent:0.5]];
[self.view addSubview:label4];
You can have a UIImageView, set its background color of your choice then place your UIlabel on it.
That will surely solve your problem.
Here is Workaround code :
UIImageView * imgView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 100, 40)];
[imgView setBackgroundColor:[UIColor brownColor]];
[self.view addSubview:imgView];
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 40)];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextAlignment:UITextAlignmentCenter];
label.text = #"My Label";
[imgView addSubview:label];
[label release];
[imgView release];
You can also achieve the same using Interface Builder.
UILabel *label = [[UILabel alloc] init];
label.text = #"Hello";
[label sizeToFit];
CGSize size = label.frame.size;
Usually we get the size of the label in this way, but text in the UILabel does not fill all space in it, there's always some margin around the text. That makes drawing label difficult to be exactly the same as visual draft. Anyone could help ?
for example: If you want to put an icon at the bottom of some text, let the margin between them be, for example 50px, and you write icon.frame = CGRectMake(10,textLabel.frame.size.height + textLabel.frame.origin.y + 50, 100, 100); but since the text can't fill all space in UILabel, so the margin in this way should be a bit larger than it should be. So I want to figure out a better way, thanks.
try with this bellow method which returns dynamic height of UILable with its text content... we this method you can set frame of UILable with its text content...
-(float) calculateHeightOfTextFromWidth:(NSString*) text: (UIFont*)withFont: (float)width :(UILineBreakMode)lineBreakMode
{
[text retain];
[withFont retain];
CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
[text release];
[withFont release];
return suggestedSize.height;
}
and use it like bellow...
UILabel *lblAddress = [[UILabel alloc]init];
[lblAddress setFrame:CGRectMake(110, 31, 200, 50)];
lblAddress.text = #"your Text ";
lblAddress.lineBreakMode = UILineBreakModeWordWrap;
lblAddress.numberOfLines = 0;
lblAddress.font = [UIFont fontWithName:#"Helvetica" size:12];
lblAddress.frame = CGRectMake(lblAddress.frame.origin.x, lblAddress.frame.origin.y,
200,[self calculateHeightOfTextFromWidth:lblAddress.text :lblAddress.font :200 :UILineBreakModeWordWrap] );
lblAddress.textColor = [UIColor darkGrayColor];
[self.view addSubview:lblAddress];
See My Blog..
i hope you get some idea from this post...
Friends,
i have created a UILabel with border (just like the image below).
I want to start my label after one/two lines left and then after finishing last line of label again one/two lines below.
Is there any way to get spacing inside label's border?
UILabel *cmntBoxlbl = [[UILabel alloc]initWithFrame:CGRectMake(58, 23, 250, 60)];
cmntBoxlbl.font=[UIFont fontWithName:#"Arial" size:12];
cmntBoxlbl.layer.borderColor = [UIColor darkGrayColor].CGColor;
cmntBoxlbl.layer.borderWidth = 1.0;
NSString *text = [NSString stringWithFormat:#"%#%#%#",#" ",[[self.DtlArray objectAtIndex:indexPath.row] objectForKey:#"comment"],#" "];
cmntBoxlbl.text = text;
cmntBoxlbl.textAlignment = UITextAlignmentCenter;
cmntBoxlbl.lineBreakMode = UILineBreakModeWordWrap;
[cmntBoxlbl setTextColor:[UIColor darkGrayColor]];
CGSize expectedLabelSize = [text sizeWithFont:cmntBoxlbl.font
constrainedToSize:cmntBoxlbl.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGRect newFrame = cmntBoxlbl.frame;
newFrame.size.height = expectedLabelSize.height;
cmntBoxlbl.frame = newFrame;
cmntBoxlbl.numberOfLines = 0;
[cmntBoxlbl sizeToFit];
[cell addSubview:cmntBoxlbl];
Make current label(commentLabel) color is white. create another label with same content and a little smaller size,place it inside the boarder.Make padding as you wish
Have you tried this-
NSString *text = [NSString stringWithFormat:#"\n\n%#%#%#\n\n",#" ",[[self.DtlArray objectAtIndex:indexPath.row] objectForKey:#"comment"],#" "];
You may create a custom view and
- (void)drawRect:(CGRect)rect {
......;
[string drawInRect:rect withFont:font lineBreakMode:mode alignment:ali];
......;
}
hope that helps
I successfully created a UIscrollview (horizontal) for 50 images and also created a label of "1 of 50" page number displaying at the top of the image along with the scroll view(for example user scroll to next image it would show 2 of 50, 3 of 50, so forth). I am able to display a label at the bottom of the image as a description. My problem is how can I create or code to display different description for each image? Im thinking of NSarray but it shows some random numbers. Is there a sample I can look at to see what I am doing wrong. you can see the description part where I am lost from there. Thanks =)
CGFloat xOffset = 0;
NSInteger pageNumber = 1;
NSUInteger i;
for (i = 1; i <= 5; i++)
{
NSString *imageName = [NSString stringWithFormat:#"creative%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageView setFrame:CGRectMake(xOffset, 0, 320, 288.5)];
[ourScrollView addSubview:imageView];
[imageView release];
UILabel *pageNumberLabel = [[UILabel alloc] initWithFrame:CGRectMake(xOffset, -10, 320, 40)];
[pageNumberLabel setText:[NSString stringWithFormat:#"%d of 5", pageNumber]];
[pageNumberLabel setTextAlignment:UITextAlignmentLeft];
[pageNumberLabel setTextColor:[UIColor whiteColor]];
[pageNumberLabel setBackgroundColor:[UIColor clearColor]];
[pageNumberLabel setFont:[UIFont fontWithName:#"MarkerFelt-Thin" size:18]];
[ourScrollView addSubview:pageNumberLabel];
[pageNumberLabel release];
NSArray *description = [NSArray arrayWithObjects:#"wow", #"bam", #"pow", #"zing", #"bling",nil];
UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(xOffset, 250, 320, 40)];
[descriptionLabel setText:[NSString stringWithFormat:#"%#", description]];
[descriptionLabel setTextAlignment:UITextAlignmentLeft];
[descriptionLabel setTextColor:[UIColor whiteColor]];
[descriptionLabel setBackgroundColor:[UIColor clearColor]];
[ourScrollView addSubview:descriptionLabel];
[descriptionLabel release];
xOffset = xOffset + 320;
pageNumber = pageNumber + 1;
You're setting the descriptionLabel with a format of #"%d", which is a decimal format. What is "description"? If it's a NSString then you should be using #"%#".
I have added multiple labels in My Tableview cell. I am displaying facebook message and sender name and photos.For some posts it might be possible that message is unavailable or photo is unavailable .. I checking null condition and if there is no value present I am not creating label for that particular cell... now some label has large string , some may have small.. I am confused with cell's height ,, I am able to get dynamic height for 1 label like this in example dynamic height but how can I manage Height according to number of label's text... my code is like
if ([(Facebook * )[tableArray objectAtIndex:indexPath.row]sender]!= nil) {
labelSender = [[UILabel alloc]initWithFrame:CGRectMake(image_view.frame.size.width+20, 20, 120, 20) ];
labelSender.text = [NSString stringWithFormat:#"%#",[(Facebook * )[tableArray objectAtIndex:indexPath.row]sender]];
[labelSender setLineBreakMode:UILineBreakModeWordWrap];
[labelSender setNumberOfLines:0];
labelSender.textColor = [UIColor colorWithRed:59/255.0 green:89/255.0 blue:153/255.0 alpha:1.0];
labelSender.font = [UIFont fontWithName:#"Arial" size:15.0];
[cell.contentView addSubview:labelSender];
[labelSender release];
}
if ([(Facebook * )[tableArray objectAtIndex:indexPath.row]post]!= nil) {
NSLog(#"post is ==%#",[(Facebook * )[tableArray objectAtIndex:indexPath.row]post]);
labelMessage = [[UILabel alloc]initWithFrame:CGRectMake(image_view.frame.size.width+20, labelSender.frame.size.height + 20, 200, 20)];
labelMessage.text = [NSString stringWithFormat:#"%#",[(Facebook * )[tableArray objectAtIndex:indexPath.row]post]];
[labelMessage setLineBreakMode:UILineBreakModeWordWrap];
[labelMessage setNumberOfLines:0];
labelMessage.backgroundColor = [UIColor yellowColor];
labelMessage.font = [UIFont fontWithName:#"Arial" size:13.0];
[cell.contentView addSubview:labelMessage];
[labelMessage release];
}
please help
I feel its better to go for UITextView whenever handling dynamic content.
You should store the displayed labels in an NSMutableArray that is a property of the cell. That way you can iterate through simply by using:
for (UILabel *tmpLabel in yourLabelArray){
// do: add height to sum
}
This will save you an the if (labelExists) for every label.
Good luck!