Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CoreText属性字符串高度计算不准确_Ios_Objective C_Uicollectionview_Core Text - Fatal编程技术网

Ios CoreText属性字符串高度计算不准确

Ios CoreText属性字符串高度计算不准确,ios,objective-c,uicollectionview,core-text,Ios,Objective C,Uicollectionview,Core Text,CoreText未提供属性字符串的正确高度(短一行或多行)。我在网上看到过很多关于这方面的帖子,但我无法理解或找到解决方案。有人能解释一下核心文本高度计算是如何工作的吗?下面是我编写的一个示例代码,显示了不准确的高度计算 上下文 我有一个集合视图,其中单元格的高度由其中的内容决定。 我正在单元格中显示文本的段落。我想通过使用核心文本进行高度计算来节省一些性能。我已经看到,通过核心文本的高度计算,我可以节省约300毫秒 代码 //高度计算 + (CGFloat)getHeight { NS

CoreText未提供属性字符串的正确高度(短一行或多行)。我在网上看到过很多关于这方面的帖子,但我无法理解或找到解决方案。有人能解释一下核心文本高度计算是如何工作的吗?下面是我编写的一个示例代码,显示了不准确的高度计算

上下文

我有一个集合视图,其中单元格的高度由其中的内容决定。 我正在单元格中显示文本的段落。我想通过使用核心文本进行高度计算来节省一些性能。我已经看到,通过核心文本的高度计算,我可以节省约300毫秒

代码

//高度计算

+ (CGFloat)getHeight
{
    NSString *text = @"The Apple HIG recommends to use a common color for links and buttons and we did just that. By using the same color throughout the app we trained the user to always associate blue to a link.The Apple HIG recommends to use a common color for links and buttons and we did just that.By using the same color throughout the app we trained the user to always associate blue to a link.";

    NSAttributedString *attrStr = [self attributedString:text withLinespacing:3 withLineBreakMode:NSLineBreakByWordWrapping];

    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attrStr));
    CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter,
                                                                    CFRangeMake(0, attrStr.length),
                                                                    NULL,
                                                                    CGSizeMake(320, 9999),
                                                                    NULL);

    return suggestedSize.height;
}
//当单元格即将显示时加载相同的文本

- (void)loadData
{
    NSString *text = @"The Apple HIG recommends to use a common color for links and buttons and we did just that.By using the same color throughout the app we trained the user to always associate blue to a link.The Apple HIG recommends to use a common color for links and buttons and we did just that.By using the same color throughout the app we trained the user to always associate blue to a link.";

    NSAttributedString *attrStr = [[self class] attributedString:text withLinespacing:3 withLineBreakMode:NSLineBreakByWordWrapping];

    // UILabel element
    self.textLabel.attributedText = attrStr;

    self.layer.borderColor = [UIColor blueColor].CGColor;
    self.layer.borderWidth = 1.0f;
}
//生成带前导、字体和换行符的属性字符串

+ (NSAttributedString *)attributedString:(NSString *)string
                        withLinespacing:(CGFloat)linespacing
                      withLineBreakMode:(NSLineBreakMode)lineBreakMode
{
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:string];
    NSInteger strLength = [string length];
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    style.lineSpacing = linespacing;
    style.lineBreakMode = lineBreakMode;

    [attrStr addAttributes:@{NSParagraphStyleAttributeName: style,
                         NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:15]} range:NSMakeRange(0, strLength)];

    return attrStr;
}
上面的代码使用核心文本计算高度,使用UILabel显示文本。UILabel对单元格有3个约束{Top:17,Leading:13px,Trailing:13px}


已知CTFrameSettersSuggestFrameSizeWithConstraints
有缺陷,返回的高度值不正确。您遇到的缺线错误非常常见,据我所知,没有好的解决方案,只有难看的解决方法,它们永远不会给出100%的准确结果

对于iOS7及以上版本,我建议转到TextKit。不知何故,在内部执行的计算确实正确,同时也基于核心文本。使用
NSLayoutManager
usedRectForTextContainer:
返回正确的结果


你可以看到一个更完整的答案。虽然这一主题并非100%,但也有一些关于核心文本计算缺陷的讨论。

CTFramesetterSuggestFrameSizeWithConstraints
已知存在缺陷,返回的高度值不正确。您遇到的缺线错误非常常见,据我所知,没有好的解决方案,只有难看的解决方法,它们永远不会给出100%的准确结果

对于iOS7及以上版本,我建议转到TextKit。不知何故,在内部执行的计算确实正确,同时也基于核心文本。使用
NSLayoutManager
usedRectForTextContainer:
返回正确的结果


你可以看到一个更完整的答案。虽然并不是100%的讨论这个话题,但也有一些关于核心文本计算错误的讨论。

感谢TextKit的提示。我需要在渲染之前计算高度,因此我使用
boundingrectfolyprange:
进行高度计算。是否可以使用UILabel进行渲染(而不是
drawGlyphsForGlyphRange:
)?使用UILabel和auto layout时,由于某种原因,标签的高度低于单元格的高度。@Praveen有可能,是的。您确定设置约束正确吗?如果要通过内容压缩阻力和内容拥抱来调整标签的大小,请记住将标签的
preferredMaxLayoutWidth
属性设置为superview的边界宽度(在
layoutSubviews
中,在调用super实现之前).我正在研究我的限制,但还没有发现我的错误。在UICollectionViewCell中,我只有一个UILabel,顶部空间为17,前导和尾随空间为13。因此,iPhone的最大宽度基本上只能是294。标签的内容压缩为750,内容拥抱为251。在LayoutSubView中调用super之前,我还将preferredMaxLayoutWidth设置为294。调用super后,标签的宽度确实是预期的294。@Praveen将内容压缩阻力和拥抱设置为1000。感谢TextKit提示。我需要在渲染之前计算高度,因此我使用
boundingrectfolyprange:
进行高度计算。是否可以使用UILabel进行渲染(而不是
drawGlyphsForGlyphRange:
)?使用UILabel和auto layout时,由于某种原因,标签的高度低于单元格的高度。@Praveen有可能,是的。您确定设置约束正确吗?如果要通过内容压缩阻力和内容拥抱来调整标签的大小,请记住将标签的
preferredMaxLayoutWidth
属性设置为superview的边界宽度(在
layoutSubviews
中,在调用super实现之前).我正在研究我的限制,但还没有发现我的错误。在UICollectionViewCell中,我只有一个UILabel,顶部空间为17,前导和尾随空间为13。因此,iPhone的最大宽度基本上只能是294。标签的内容压缩为750,内容拥抱为251。在LayoutSubView中调用super之前,我还将preferredMaxLayoutWidth设置为294。调用super后,标签的宽度确实是预期的294。@Praveen将内容压缩阻力和拥抱设置为1000。