在ios7中,sizeWithFont:现在已弃用。我现在如何在UIFont对象传递到替换方法sizeWithAttributes:?
当前回答
试试这个语法:
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:@{NSFontAttributeName: font}];
其他回答
使用动态高度的多行标签可能需要额外的信息来正确设置大小。你可以使用sizeWithAttributes with UIFont和NSParagraphStyle来指定字体和换行模式。
你可以像这样定义段落样式并使用NSDictionary:
// 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];
你可以使用CGSize ' adjuststedsize '或CGRect作为矩形。size.height属性如果你在寻找高度。
更多关于NSParagraphStyle的信息请访问:https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSParagraphStyle_Class/Reference/Reference.html
我创建了一个类别来处理这个问题,它是:
#import "NSString+StringSizeWithFont.h"
@implementation NSString (StringSizeWithFont)
- (CGSize) sizeWithMyFont:(UIFont *)fontToUse
{
if ([self respondsToSelector:@selector(sizeWithAttributes:)])
{
NSDictionary* attribs = @{NSFontAttributeName:fontToUse};
return ([self sizeWithAttributes:attribs]);
}
return ([self sizeWithFont:fontToUse]);
}
这样你只需要找到/替换sizeWithFont: sizeWithMyFont:你就可以了。
I believe the function was deprecated because that series of NSString+UIKit functions (sizewithFont:..., etc) were based on the UIStringDrawing library, which wasn't thread safe. If you tried to run them not on the main thread (like any other UIKit functionality), you'll get unpredictable behaviors. In particular, if you ran the function on multiple threads simultaneously, it'll probably crash your app. This is why in iOS 6, they introduced a the boundingRectWithSize:... method for NSAttributedString. This was built on top of the NSStringDrawing libraries and is thread safe.
如果你看一下新的NSString boundingRectWithSize:…在NSAttributeString函数中,它以与NSAttributeString相同的方式请求一个属性数组。如果我不得不猜测,ios7中的这个新的NSString函数仅仅是ios6中NSAttributeString函数的包装。
在这一点上,如果你只支持iOS 6和iOS 7,那么我肯定会改变你所有的NSString sizeWithFont:…NSAttributeString boundingRectWithSize。如果您恰好有一个奇怪的多线程极端情况,它将为您省去很多麻烦!下面是我如何转换NSString sizeWithFont:constrainedToSize::
过去是什么样子:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];
可替换为:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:@{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
请注意文件中提到:
在iOS 7及更高版本中,此方法返回分数大小(在size . size中) 返回的CGRect的组件);要使用返回的大小到大小 视图中,必须使用将其值提高到最近的更高整数 使用cell函数。
因此,要抽出计算的高度或宽度,以用于调整视图,我将使用:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
这些在ios 7中都不适用。这是我最后做的事情。我把它放在我的自定义单元格类中,并在highightforcellatindexpath方法中调用该方法。
当在应用商店中查看应用程序时,我的单元格看起来与描述单元格相似。
首先在故事板中,将标签设置为'attributedText',将行数设置为0(这将自动调整标签的大小(仅限ios 6+)),并将其设置为换行。
然后我只是在我的自定义单元格类中添加单元格内容的所有高度。在我的例子中,我在顶部有一个标签,总是说“描述”(_descriptionHeadingLabel),一个较小的标签,大小可变,包含实际的描述(_descriptionLabel),从单元格的顶部到标题(_descriptionHeadingLabelTopConstraint)的约束。我还添加了3来留出底部的空间(大约与apple在subtitle type cell上的位置相同)。
- (CGFloat)calculateHeight
{
CGFloat width = _descriptionLabel.frame.size.width;
NSAttributedString *attributedText = _descriptionLabel.attributedText;
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} options: NSStringDrawingUsesLineFragmentOrigin context:nil];
return rect.size.height + _descriptionHeadingLabel.frame.size.height + _descriptionHeadingLabelTopConstraint.constant + 3;
}
在我的表格视图委托中
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (indexPath.row == 0) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"descriptionCell"];
DescriptionCell *descriptionCell = (DescriptionCell *)cell;
NSString *text = [_event objectForKey:@"description"];
descriptionCell.descriptionLabel.text = text;
return [descriptionCell calculateHeight];
}
return 44.0f;
}
你可以改变if语句,让它更“聪明”一点,从某种数据源中获取单元格标识符。在我的例子中,单元格将被硬编码,因为它们将以特定的顺序固定数量。
你仍然可以使用sizeWithFont。但是,在iOS >= 7.0中,如果字符串包含开头和结尾空格或结束行\n,则会导致崩溃。
在使用文本之前修剪文本
label.text = [label.text stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
这也适用于sizeWithAttributes和[label sizeToFit]。
此外,当你有nsstringdrawingtextstorage消息发送到deallocated实例在ios7.0设备它处理这个。
推荐文章
- 如何停止不必要的UIButton动画标题变化?
- 如何在我的iPhone应用程序中使用NSError ?
- Objective-C中的自动引用计数不能防止或减少什么样的泄漏?
- 如何忽略Python中的弃用警告
- 如何精确地以毫秒为单位记录方法的执行时间?
- 保存字符串到NSUserDefaults?
- 查看保存的NSUserDefaults的简单方法?
- 如何添加UITableViewCell之间的间距
- 在为设备编译时,Apple Mach-O连接器错误
- 理解设置
- 架构i386的未定义符号:_OBJC_CLASS_$_SKPSMTPMessage",引用自:错误
- Objective-C中方法混合的危险是什么?
- 如何使用接口生成器创建的nib文件加载UIView
- 如何设置回退按钮文本在Swift
- 如何比较两个nsdate:哪个是最近的?