In iOS 7, sizeWithFont:
is now deprecated. How do I now pass in the UIFont object into the replacement method sizeWithAttributes:
?
Multi-line labels using dynamic height may require additional information to set the size properly. You can use sizeWithAttributes with UIFont and NSParagraphStyle to specify both the font and the line-break mode.
You would define the Paragraph Style and use an NSDictionary like this:
// set paragraph style
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByWordWrapping];
// make dictionary of attributes with paragraph style
NSDictionary *sizeAttributes = @{NSFontAttributeName:myLabel.font, NSParagraphStyleAttributeName: style};
// get the CGSize
CGSize adjustedSize = CGSizeMake(label.frame.size.width, CGFLOAT_MAX);
// alternatively you can also get a CGRect to determine height
CGRect rect = [myLabel.text boundingRectWithSize:adjustedSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:sizeAttributes
context:nil];
You can use the CGSize 'adjustedSize' or CGRect as rect.size.height property if you're looking for the height.
More info on NSParagraphStyle here: https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSParagraphStyle_Class/Reference/Reference.html
Better use automatic dimensions (Swift):
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
NB: 1. UITableViewCell prototype should be properly designed (for the instance don't forget set UILabel.numberOfLines = 0 etc) 2. Remove HeightForRowAtIndexPath method
VIDEO: https://youtu.be/Sz3XfCsSb6k
Building on @bitsand, this is a new method I just added to my NSString+Extras category:
- (CGRect) boundingRectWithFont:(UIFont *) font constrainedToSize:(CGSize) constraintSize lineBreakMode:(NSLineBreakMode) lineBreakMode;
{
// set paragraph style
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:lineBreakMode];
// make dictionary of attributes with paragraph style
NSDictionary *sizeAttributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: style};
CGRect frame = [self boundingRectWithSize:constraintSize options:NSStringDrawingUsesLineFragmentOrigin attributes:sizeAttributes context:nil];
/*
// OLD
CGSize stringSize = [self sizeWithFont:font
constrainedToSize:constraintSize
lineBreakMode:lineBreakMode];
// OLD
*/
return frame;
}
I just use the size of the resulting frame.
Here is the monotouch equivalent if anyone needs it:
/// <summary>
/// Measures the height of the string for the given width.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="width">The width.</param>
/// <param name="padding">The padding.</param>
/// <returns></returns>
public static float MeasureStringHeightForWidth(this string text, UIFont font, float width, float padding = 20)
{
NSAttributedString attributedString = new NSAttributedString(text, new UIStringAttributes() { Font = font });
RectangleF rect = attributedString.GetBoundingRect(new SizeF(width, float.MaxValue), NSStringDrawingOptions.UsesLineFragmentOrigin, null);
return rect.Height + padding;
}
which can be used like this:
public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
//Elements is a string array
return Elements[indexPath.Row].MeasureStringHeightForWidth(UIFont.SystemFontOfSize(UIFont.LabelFontSize), tableView.Frame.Size.Width - 15 - 30 - 15);
}
boundingRectWithSize:options:attributes:context:
Accepted answer in Xamarin would be (use sizeWithAttributes and UITextAttributeFont):
UIStringAttributes attributes = new UIStringAttributes
{
Font = UIFont.SystemFontOfSize(17)
};
var size = text.GetSizeUsingAttributes(attributes);