ios – 垂直对齐UILabel文本与约束,无换行(自动布局,单行)

栏目: IOS · 发布时间: 5年前

内容简介:所以我在IB中设置我的视图,使得这个文本标签通过约束与缩略图的顶部对齐.但是,我们知道,您不能在UILabel中垂直对齐文本.我的文字根据内容的长度来更新字体大小.全尺寸文本看起来不错,而小文本在视图上显着更低.

所以我在IB中设置我的视图,使得这个文本标签通过约束与缩略图的顶部对齐.

但是,我们知道,您不能在UILabel中垂直对齐文本.我的文字根据内容的长度来更新字体大小.全尺寸文本看起来不错,而小文本在视图上显着更低.

existing solution 涉及调用sizeToFit或更新uilabel的框架以匹配文本的高度.不幸的是,后者(虽然丑的)解决方案不适合你不应该更新框架的约束.当您需要使文本自动收缩直到截断时,前一个解决方案基本上不起作用. (所以它不适用于有限数量的行和自动收缩).

现在,为什么uilabel的内在大小(高度)不会像宽度那样更新,当它被设置为通过“大小适合内容”的自然大小超出了我.似乎肯定应该,但它不.

所以我找不到替代解决方案.据我所见,您可能必须在标签上设置高度约束,并在计算文本的高度后调整高度.任何人都有很好的解决方案?

这个问题是一个真正的PITA来解决.这并不意味着API的工作在iOS7中已被淘汰,或者iOS7更换API被破坏.胡说!

您的解决方案很好,但是它使用了不推荐的API(sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode :),并且封装不是很好 – 您需要将此代码复制到您想要此行为的任何单元格或视图.在正面上它是相当有效率!一个错误可能是,当您进行计算时,标签尚未布局,但您可以根据其宽度进行计算.

我建议您将此行为封装在UILabel子类中.通过将尺寸计算放在被覆盖的intrinsicContentSize方法中,标签将自动调整大小.我写了以下内容,其中包含将在iOS6上执行的代码,我的版本使用不被弃用的API用于iOS7或更高版本:

@implementation TSAutoHeightLabel

- (CGSize) intrinsicContentSize
{
    NSAssert( self.baselineAdjustment == UIBaselineAdjustmentAlignCenters, @"Please ensure you are using UIBaselineAdjustmentAlignCenters!" );

    NSAssert( self.numberOfLines == 1, @"This is only for single-line labels!" );

    CGSize intrinsicContentSize;

    if ( [self.text respondsToSelector: @selector( boundingRectWithSize:options:attributes:context: )] )
    {
        NSStringDrawingContext* context = [NSStringDrawingContext new];
        context.minimumScaleFactor = self.minimumScaleFactor;

        CGSize inaccurateSize = [self.text boundingRectWithSize: CGSizeMake( self.bounds.size.width, CGFLOAT_MAX )
                                                        options: NSStringDrawingUsesLineFragmentOrigin
                                                     attributes: @{ NSFontAttributeName : self.font }
                                                        context: context].size;

        CGSize accurateSize = [self.text sizeWithAttributes: @{ NSFontAttributeName : [UIFont fontWithName: self.font.fontName size: 12.0] } ];

        CGFloat accurateHeight = accurateSize.height * inaccurateSize.width / accurateSize.width;

        intrinsicContentSize = CGSizeMake( inaccurateSize.width, accurateHeight);
    }
    else
    {
        CGFloat actualFontSize;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

        [self.text sizeWithFont: self.font
                    minFontSize: self.minimumFontSize
                 actualFontSize: &actualFontSize
                       forWidth: self.frame.size.width
                  lineBreakMode: NSLineBreakByTruncatingTail];

#pragma GCC diagnostic pop

        CGRect lineBox = CTFontGetBoundingBox((__bridge CTFontRef)([UIFont fontWithName: self.font.fontName size: actualFontSize]));

        intrinsicContentSize = lineBox.size;
    }

    return intrinsicContentSize;
}

@end

这个实现并不完美.我必须确保使用baselineAdjustment == UIBaselineAdjustmentAlignCenters,我不知道为什么100%肯定.我不满意我不得不跳过的篮球,以获得准确的文字高度.我的计算产生和您的数据之间也有一些像素差异.随意玩,随意调整:)

boundingRectWithSize:options:attributes:context API对我来说好像很坏.虽然(主要是)正确地将文本约束到输入大小,但它不会计算正确的高度!它返回的高度是基于所提供的字体的行高,即使是缩放比例.我的猜测是,这是为什么UILabel默认情况下没有这种行为?我的解决方法是计算高度和宽度都准确的无约束尺寸,然后使用受约束宽度和无约束宽度之间的比率来计算约束尺寸的准确高度.什么是PITA在Apple开发论坛中有很多投诉,而在这里,SO指出,这个API有一些这样的问题.

http://stackoverflow.com/questions/15510875/vertically-align-uilabel-text-with-constraints-and-no-wrap-auto-layout-single


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java RESTful Web Service实战

Java RESTful Web Service实战

韩陆 / 机械工业出版社 / 2014-10-1 / 69.00

国内首本完整、深度地讲解如何基于Java标准规范实现REST风格的Web服务的专著,阿里巴巴Java技术专家12年开发经验结晶,3位业内著名技术专家联袂推荐!不仅深刻解读了最新的JAX-RS标准和其API设计,以及Jersey的使用要点和实现原理,而且系统讲解了REST的基本理论,更重要的是从实践角度深度讲解了如何基于Jersey实现完整的、安全的、高性能的REST式的Web服务。 《Jav......一起来看看 《Java RESTful Web Service实战》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码