I just want to know number of lines, given the font, constraints, and the text. Can I figure it out without creating a UILabel?
+ (int)numberOfLines:(NSDictionary *)data{
NSString *myString = [some string calculation];
CGSize sizeConstrain = CGSizeMake(some constrain calculation);
CGSize stringSize = [myString sizeWithFont:someFont constrainedToSize:sizeConstrain];
CGRect labelFrame = CGRectMake(0,
0,
stringSize.width,
stringSize.height + 2);
UILabel *label = [[UILabel alloc]initWithFrame:labelFrame];
label.text = myString;
return label.numberOfLines;
}
Yes
+ (int)numberOfLines:(NSDictionary *)data{
NSString *myString = [some string calculation];
CGSize sizeConstrain = CGSizeMake(some constrain calculation);
CGSize stringSize = [myString sizeWithFont:someFont constrainedToSize:sizeConstrain];
return (stringSize.height/someFont.lineHeight);
}
EDIT: I used this for UITextView and iOS7
- (CGFloat) getRowsForText:(NSString*) text{
CGFloat fixedWidth = 300;
UIFont *font = [UIFont fontWithName:#"HelveticaNeue" size:14];
NSMutableParagraphStyle *paragrapStyle = [[NSMutableParagraphStyle alloc] init];
paragrapStyle.alignment = NSTextAlignmentLeft;
textStepAttr = [NSDictionary dictionaryWithObjectsAndKeys:
font,NSFontAttributeName,
paragrapStyle, NSParagraphStyleAttributeName,
nil];
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:textStepAttr];
CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(fixedWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
return (rect.size.height / font.lineHeight) ;
}
Related
Hello I'm working on chat app in which user can send smiley (emoji) to other user. For text its working perfect but when it contains emoji then it is correct. I have used method for this
- (CGSize)getSizeForText:(NSString *)text maxWidth:(CGFloat)width font:(NSString *)fontName fontSize:(float)fontSize {
CGSize constraintSize;
constraintSize.height = MAXFLOAT;
constraintSize.width = width;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:fontName size:fontSize], NSFontAttributeName,
nil];
CGRect frame = [text boundingRectWithSize:constraintSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:attributesDictionary
context:nil];
CGSize stringSize = frame.size;
return stringSize;
}
and the results are something like
As from images you can see what i want to say and what i need. I need some between two lines when there is emoji text in UILabel. Any help will be appreciated. Thanks in advance.
Edit: I have given answer on this. But if some have some quick hack for this then that will be great for me.
I have made a good work to do it manually and it looks good for me now. I have added linespacing for label text and it works good for me. I have set text like
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"%#",message_text]];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:4];
[attrString addAttribute:NSParagraphStyleAttributeName
value:style
range:NSMakeRange(0, [message_text length])];
lblChatMSG.attributedText = attrString;
and my method to get height of text is
- (CGSize)getSizeForText:(NSString *)text maxWidth:(CGFloat)width font:(NSString *)fontName fontSize:(float)fontSize {
CGSize constraintSize;
constraintSize.height = MAXFLOAT;
constraintSize.width = width;
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
paragraphStyle.lineSpacing = 4;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:fontName size:fontSize], NSFontAttributeName,paragraphStyle,NSParagraphStyleAttributeName,
nil];
CGRect frame = [text boundingRectWithSize:constraintSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:attributesDictionary
context:nil];
CGSize stringSize = frame.size;
return stringSize;
}
And the result is
I just increased the required height of the label and adjusted its origin.
// Expand label to avoid cutoff emojis
label.frame.size.height += 8.0
label.frame.origin.y -= 4.0
Can anyone please help me to fix this warning?
'sizeWithFont:constrainedToSize:lineBreakMode:' is deprecated: first deprecated in iOS 7.0 - Use -boundingRectWithSize:options:attributes:context:
-(CGFloat)setLableSizeAccordingToText:(NSString*)text andSetX:(CGFloat)x Y:(CGFloat)y{
self.text = text;
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);
CGSize expectedLabelSize = [text sizeWithFont:self.font constrainedToSize:maximumLabelSize lineBreakMode:self.lineBreakMode];
CGRect frame = CGRectMake(x, y, expectedLabelSize.width+lblHorizontalPadding , lblHeight);
self.frame = frame;
return expectedLabelSize.width + lblHorizontalPadding;
}
It is working for me
UILabel *myLabel;
CGSize textSize;
if (!SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")){
textSize = [myLabel.text sizeWithFont:[myLabel font]];
}else{
textSize = [myLabel.text sizeWithAttributes:[NSDictionary dictionaryWithObject:[myLabel font] forKey:NSFontAttributeName]];
}
Try using this
+ (CGSize)DescriptionHeight:(NSString *)str{
CGSize detailSize = [str boundingRectWithSize:CGSizeMake(300, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{
NSFontAttributeName:[UIFont fontWithName:#"Cronos Pro" size:14.0f]
}
context:nil].size;
return detailSize;
}
Or u can use in this way too
CGSize stringsize = [Your_Str_Value sizeWithAttributes:#{NSFontAttributeName: [UIFont systemFontOfSize:16.0f]}];
YourBtn.frame = CGRectMake(10, 5, stringsize.width, 44);
The new sizeWithAttributes combined with NSParagraphStyle should do the job for you.
NSMutableDictionary *attributes = [NSMutableDictionary new];
[attributes setObject:self.font forKey:NSFontAttributeName];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = self.lineBreakMode;
//paragraphStyle.alignment = self.textAlignment; //uncomment this if you need specific text alignment
[attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
CGSize expectedLabelSize = [text sizeWithAttributes:attributes];
Im having troubles calculating the max label height of a group of labels. I have the following code:
-(double)calcMaxHeight:(NSDictionary *)fields withFont:(UIFont *)font {
double maxRowHeigth = 0;
NSArray *keys = [fields allKeys];
for(NSString *key in keys) {
NSDictionary *dic = [fields objectForKey:key];
UILabel *aux = [[UILabel alloc] init];
[aux setNumberOfLines:0];
[aux setText:[dic objectForKey:#"text"]];
[aux setFont:font];
[aux setLineBreakMode:NSLineBreakByWordWrapping];
CGSize maxSize = CGSizeMake([[dic objectForKey:#"value"] doubleValue],MAXFLOAT);
CGSize auxSize = [aux sizeThatFits:maxSize];
if(auxSize.height > maxRowHeigth)
maxRowHeigth = auxSize.height;
}
return maxRowHeigth;
}
And this code "works". The problem is that i need to calculate the label size when the text has paddings because, in the drawTextInRect method, i add an UIEdgeInsetsof {3,3,3,3}.
So, how can i calculate the UILabel size counting with the padding? I tried overriding the sizeThatFits method, but im missing something yet:
-(CGSize)sizeThatFits:(CGSize)size {
NSString *text=self.text;
double width = size.width - 6;
CGSize nSize = CGSizeMake(width, size.height);
CGSize stringSize = [text boundingRectWithSize:nSize
options:NSStringDrawingTruncatesLastVisibleLine |
NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName : self.font}
context:nil].size;
return stringSize;
}
With this, i cant see the whole text when it occupies more than 1 row.
Thank you.
Regards.
This will give you the height of the string and therefore the label:
- (CGSize)sizeForString:(NSString *)text font:(UIFont *)font maxHeight:(CGFloat)maxHeight maxWidth:(CGFloat)maxWidth {
NSDictionary *stringAttributes = #{NSFontAttributeName : font};
CGSize stringLength = [text boundingRectWithSize:CGSizeMake(maxWidth, maxHeight
options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin
attributes:stringAttributes
context:nil].size;
return stringLength;
}
I've create a UILabel.When the text is too long, I hope to use (.. more) to replace (...).I have already tried it,but I did not demand results.
UILabel * writtenContentLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 0, ScreenWidth - 20 , 70)];
writtenContentLabel.numberOfLines = 0;
writtenContentLabel.text = [str stringByAppendingString:#"More"];
writtenContentLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
[self addSubview:writtenContentLabel];
How do I do?
You have to use a custom label view to achieve this.
Replace your UILabels with any of the following custom labels. Both of them support custom truncationTokenString method.
MDHTMLLabel https://github.com/mattdonnelly/MDHTMLLabel (I recommend this control)
TTTAtributtedLabel https://github.com/mattt/TTTAttributedLabel
You can change the default ellipsis using,
[label setTruncationTokenString:#"...More"];
You can use the following method:
- (NSString*)stringWithElipsisMore:(NSString*)oringinalStr withLabel:(UILabel*)label
{
CGRect rect = label.frame;
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
NSDictionary * attributes = #{NSFontAttributeName:label.font, NSParagraphStyleAttributeName:paragraphStyle};
const CGSize maxSize = CGSizeMake(rect.size.width, CGFLOAT_MAX);
CGSize stringSize = [oringinalStr boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
if (stringSize.height > rect.size.height) {
float proportion = rect.size.height / stringSize.height;
NSString *subStr = [oringinalStr substringToIndex:oringinalStr.length * proportion];
CGSize stringSize = [subStr boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
while (stringSize.height < rect.size.height) {
subStr = [oringinalStr substringToIndex:subStr.length + 1];
stringSize = [subStr boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
}
subStr = [subStr substringToIndex:subStr.length - 1];
while (stringSize.height > rect.size.height){
subStr = [subStr substringToIndex:subStr.length - 1];
stringSize = [subStr boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
}
NSRange range = NSMakeRange(subStr.length - 7, 7);
NSString *subSubStr = [subStr stringByReplacingCharactersInRange:range withString:#"...more"];
return subSubStr;
} else {
return oringinalStr;
}
}
NSString *subStr = [self stringWithElipsisMore:str withLabel:writtenContentLabel];
writtenContentLabel.text = subStr;
I have a multiple lines UILabel with attributed text.
All the lines in the text are of the same font, but each line is of a different font size.
I'm trying to achieve the exact same vertical space between each line.
However what is being displayed has variable spaces. It is as if something is adding a vertical margin to the font based on the font size.
CGFloat y = 0;
NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:#""];
NSArray *linesArray = [NSArray arrayWithObjects:#"One I\n",
#"Two I\n",
#"Three I\n",
#"Four I\n",
#"Five I\n", nil];
CGFloat fontSize = 10.0;
for(NSString *line in linesArray) {
NSMutableAttributedString *attributedLine = [[NSMutableAttributedString alloc] initWithString:line];
NSInteger stringLength=[line length];
[attributedLine addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"TimesNewRomanPSMT" size:fontSize]
range:NSMakeRange(0, stringLength)];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 0.0f;
paragraphStyle.alignment = NSTextAlignmentRight;
[attributedLine addAttributes:#{ NSParagraphStyleAttributeName : paragraphStyle} range:NSMakeRange(0, stringLength)];
[attString appendAttributedString:attributedLine];
fontSize += 10.0;
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
label.numberOfLines = 0;
label.attributedText = attString;
[label sizeToFit];
CGRect newFrame = label.frame;
newFrame.size.width = self.view.frame.size.width - 40;
newFrame.origin.y = y;
newFrame.origin.x = 0;
label.frame = newFrame;
[self.view addSubview:label];
Any suggestions on the code I should use in order for it to display no space at all between each line of text?
I have been doing something similar, so maybe you could try something like this (typed in browser, watch out!):
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment: NSTextAlignmentRight];
[style setLineSpacing:0];
for(NSString *line in linesArray) {
NSMutableParagraphStyle *subStyle = [style mutableCopy];
[subStyle setMaximumLineHeight:10]; // play around with this value <-----
NSDictionary *attributes =
#{
NSFontAttributeName : [UIFont fontWithName:#"TimesNewRomanPSMT" size:fontSize],
NSParagraphStyleAttributeName : paragraphStyle,
};
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:line attributes: attributes]];
fontSize += 10.0;
}