简体   繁体   English

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

[英]Single line UILabel hugging not working with autoshrink

I've a UILabel with the following properties: 我有一个具有以下属性的UILabel:

  • A very big font 很大的字体
  • Fixed left margin to superview 固定左边距为超级视图
  • Fixed right margin to superview 固定了要观看的右边距
  • Centered vertically 垂直居中
  • Autoshrinks to a minimum font size to avoid truncating the text as much as possible. Autoshrinksminimum font size以避免尽可能地截断文本。
  • Single line 单线
  • Vertical hugging priority set to Required (1000) 垂直拥抱优先级设置为“ Required (1000)

The problem I'm having is that the label doesn't vertically hug the text , as you can see in the image bellow there's a lot of space on top and bellow the text. 我遇到的问题是标签没有垂直地拥抱文本 ,正如您在下面的图像中可以看到的那样,在文本的顶部和下面有很多空间。

I uploaded the sample project here . 我在这里上传了示例项目。

Thanks! 谢谢!

在此处输入图片说明在此处输入图片说明在此处输入图片说明

试试下面的代码:

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

I was able to achieve the desired effect with a workaround. 通过变通办法,我能够达到预期的效果。 It's not the perfect solution and doesn't work on all cases but it did solve my issue at least. 这不是一个完美的解决方案,并且不适用于所有情况,但至少确实解决了我的问题。

SUMMARY 摘要

The workaround works as follows: 解决方法如下:

  1. Find the actual font (the font that is being actually used by the label). 查找actual font (标签实际使用的字体)。
  2. Calculate the text height with the actual font. 用实际字体计算文字高度。
  3. Use UIViews 's - (UIEdgeInsets)alignmentRectInsets ( reference ) to modify alignment rect that is used by Autolayout to position views based on the actual text height. 使用UIViews- (UIEdgeInsets)alignmentRectInsets参考 ),以修改用于通过自动布局基于实际文本高度来定位视图对准RECT。

With all this, I was able to go from this: 有了所有这些,我就可以做到这一点:

在此处输入图片说明

to this: 对此:

在此处输入图片说明

PROBLEMS 问题

  • Need to set baseline to center 需要将基线设置为居中
  • Only implemented for exceeding height (doesn't work for right and left margins) 仅在超出高度时才实现(对左右边距无效)
  • Only for single line labels 仅用于单行标签

CODE

Declared a UILabel subclass as follows 声明一个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

Demo project can be downloaded for here 演示项目可以在这里下载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM