【问题标题】:ios Dynamic sizing labelsios 动态尺寸标签
【发布时间】:2012-02-29 04:23:05
【问题描述】:

我尝试在网上搜索,但没有找到我的问题的明确答案,所以我来寻求您的专家建议。我有一个带有 2 个标签的视图。第一个标签用于显示名称的缩写,2-3 个字母。第二个标签显示全名。

我的问题是,是否有办法根据给定的字体类型、大小和字符串长度动态调整标签大小?我问是因为我希望第二个标签靠近第一个标签,两者之间没有太多空白空间,或者第一个标签与第二个标签不重叠。

这不是全部在一个标签中的原因是因为第一个标签应该比第二个标签有更大的字体和不同的配色方案。

非常感谢任何建议。

【问题讨论】:

标签: ios text uilabel font-size


【解决方案1】:

您可以计算字符串出现的大小,然后可以将 UILabel 的框架设置为该大小,请参阅以下代码作为示例 -

//Calculate the expected size based on the font and linebreak mode of your label
CGSize maximumLabelSize = CGSizeMake(296,9999);

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font 
                        constrainedToSize:maximumLabelSize 
                        lineBreakMode:yourLabel.lineBreakMode]; 

//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;

更新 -

改用sizeWithAttributes:,它现在需要NSDictionary。使用键 UITextAttributeFont 和您的字体对象传递对,如下所示:

CGSize size = [string sizeWithAttributes:
                       @{NSFontAttributeName:
                         [UIFont systemFontOfSize:17.0f]}];

查看Replacement for deprecated sizeWithFont: in iOS 7?了解更多详情

【讨论】:

  • 您先生是个救世主。我仍在努力学习 iOS API 以及一切应该如何工作。
  • @Seb - 祝你好运!快乐编程!
  • 这部分代码:lineBreakMode:yourLabel.lineBreakMode is not for IOS 6
  • sizeWithFont 已弃用。任何好的替代例子真的可以帮助我..?
【解决方案2】:

这也可以解决问题,并将考虑到属性文本

label.attributedText = attrString;
CGSize maximumLabelSize = CGSizeMake(187,CGFLOAT_MAX);
CGSize requiredSize = [label sizeThatFits:maximumLabelSize];
CGRect labelFrame = label.frame;
labelFrame.size.height = requiredSize.height;
label.frame = labelFrame;

【讨论】:

  • 这个解决方案更明智。 UILabel 应该负责大小,而不是 NSString
  • 什么是 CGFLOAT_MAX ??
  • 浮点型变量可以存储的最大值。
  • attrString 会用什么代替?
【解决方案3】:

'sizeWithFont:' 已弃用:在 iOS 7.0 中首次弃用。

所以试试sizeWithAttributes

- (void)viewDidLoad
{
    [super viewDidLoad];

    label = [[UILabel alloc] initWithFrame:CGRectMake(20, 40, 300, 20)];

    label.backgroundColor = [UIColor blueColor];

     const CGFloat fontSize = 30;
     UIFont *regularFont = [UIFont systemFontOfSize:fontSize];
     UIColor *foregroundColor = [UIColor blackColor];

     attrs = [NSDictionary dictionaryWithObjectsAndKeys:
     regularFont, NSFontAttributeName,
     foregroundColor, NSForegroundColorAttributeName
     , nil];

     NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc]
     initWithString:@"Test Text"
     attributes:attrs];

     [label setAttributedText:attributedText];
     [self.view addSubview:label];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGSize expectedLabelSize = [label.text sizeWithAttributes:attrs]; // iOS 7 Code <--

    CGRect newFrame = label.frame;
    newFrame.size.width = expectedLabelSize.width;
    label.frame = newFrame;

    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc]
                                                 initWithString:@"Longer Test Text"
                                                 attributes:attrs];

    [label setAttributedText:attributedText];
}

【讨论】:

    【解决方案4】:

    由于 sizeWithFont: 在 iOS 7 中已弃用,您需要使用 sizeWithAttributes(正如 maver 解释的 here)。为了简化代码,您可以添加一个可以重用的方法,如下所示:

    -(CGRect)rectForText:(NSString *)text 
               usingFont:(UIFont *)font 
           boundedBySize:(CGSize)maxSize
    {
        NSAttributedString *attrString =
            [[NSAttributedString alloc] initWithString:text
                                            attributes:@{ NSFontAttributeName:font}];
    
        return [attrString boundingRectWithSize:maxSize
                                        options:NSStringDrawingUsesLineFragmentOrigin
                                        context:nil];
    }
    

    并利用它

    CGSize maximumLabelSize = CGSizeMake(280,9999);
    UIFont *font = [UIFont systemFontOfSize:20];
    CGRect titleRect = [self rectForText:post.title // <- your text here 
                               usingFont:font
                           boundedBySize:maximumLabelSize];
    

    【讨论】:

      【解决方案5】:

      除了 Saurabh 的回答。我遇到了同样的问题,您应该添加这一行
      [yourLabel setNumberOfLines:0];
      以便整个文本以 X 行显示。

      【讨论】:

      • 是的,在设置 numberOfLines=0 后我的问题解决了,否则我在实施 Saurabh 的解决方案时会用头撞屏幕。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多