单行 UILabel 拥抱不适用于自动收缩

Single line UILabel hugging not working with autoshrink

我有一个具有以下属性的 UILabel:

我遇到的问题是标签 没有垂直紧贴文本 ,如下图所示,有很多 space在顶部并在文本下方。

我上传了示例项目here

谢谢!

试试下面的代码:

[self.myLabel setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth]; 

我能够通过解决方法达到预期的效果。这不是完美的解决方案,并不适用于所有情况,但它至少解决了我的问题。

摘要

解决方法如下:

  1. 找到actual font(标签实际使用的字体)。
  2. 用实际字体计算文字高度。
  3. 使用 UIViews- (UIEdgeInsets)alignmentRectInsets (reference) 修改对齐矩形,Autolayout 使用它根据实际文本高度定位视图。

有了这一切,我可以从这里开始:

对此:

问题

  • 需要将基线设置为中心
  • 仅在超出高度时实施(不适用于左右边距)
  • 仅适用于单行标签

代码

声明了一个UILabel子类如下

@implementation HuggingLabel

- (UIEdgeInsets)alignmentRectInsets
{
    if (self.numberOfLines != 1)
    {
        if ([super respondsToSelector:@selector(alignmentRectInsets)])
            return [super alignmentRectInsets];
        else
            return UIEdgeInsetsZero;
    }

    UIFont *fontThatFitsBounds = [self fontThatFitsBounds];
    CGSize textSize = [self.text sizeWithAttributes:@{
                                                      NSFontAttributeName : fontThatFitsBounds
                                                      }];
    CGSize actualSize = self.bounds.size;

    CGFloat exceedingWidth = actualSize.width = textSize.width;
    CGFloat exceedingHeight = actualSize.height - textSize.height;
    CGFloat exceedingHeightTop = exceedingHeight / 2.0f;
    CGFloat exceedingHeightBottom = MAX(0.0f, exceedingHeight / 2.0f + fontThatFitsBounds.descender);

    UIEdgeInsets insets = UIEdgeInsetsMake(
                                           exceedingHeightTop,
                                           0.0f,
                                           exceedingHeightBottom,
                                           0.0f
                                           );

    return insets;
}

- (UIFont *)fontThatFitsBounds
{
    CGSize currentSize = CGSizeZero;
    CGFloat fontSizeThatFits = self.font.pointSize + 1.0f;

    do {

        fontSizeThatFits = fontSizeThatFits - 1.0f; //try with one point smaller size

        NSDictionary *attributes = [self stringAttributesWithFontOfSize:fontSizeThatFits];
        currentSize = [self.text sizeWithAttributes:attributes];

    } while (currentSize.width > self.bounds.size.width ||
             currentSize.height > self.bounds.size.height);

    return [self.font fontWithSize:fontSizeThatFits];
}

- (NSDictionary *)stringAttributesWithFontOfSize:(CGFloat)fontSize
{
    NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = self.lineBreakMode;
    paragraphStyle.alignment = self.textAlignment;

    NSDictionary *attributes = @{
                                 NSFontAttributeName : [self.font fontWithSize:fontSize],
                                 NSParagraphStyleAttributeName : paragraphStyle
                                 };

    return attributes;
}

@end

可以下载演示项目 here