xcode iOS 动态调整样式 UILabel 的大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15861190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:09:02  来源:igfitidea点击:

iOS resize styled UILabel dynamically

iphoneiosxcodeuilabel

提问by Danny Hiemstra

I have added a UILabelwith a fixed with and initial height to the bottom of my scrollview via the storyboard. Via the UIViewContollerI give the UILabela white background and rounded corners and load text into the label dynamically.

我已经UILabel通过情节提要在我的滚动视图底部添加了一个固定高度和初始高度。通过UIViewContoller我给UILabel白色背景和圆角并动态地将文本加载到标签中。

What I want to do is resize the label height based on the text. I have read tons of posts on stackoverflow on how to do this and tried them all and none of them seem to work.

我想要做的是根据文本调整标签高度的大小。我在 stackoverflow 上阅读了大量关于如何执行此操作的帖子,并尝试了所有这些帖子,但似乎没有一个有效。

To bring down the problem I use the following code:

为了解决这个问题,我使用以下代码:

descriptionLabel.numberOfLines = 0;
descriptionLabel.text = @"Nam nisi arcu, sodales vitae scelerisque sit amet. Nam nisi arcu, sodales vitae scelerisque sit amet. Nam nisi arcu, sodales vitae scelerisque sit amet.";
[descriptionLabel sizeToFit];

The result of this is that the label will cut of the text like this: enter image description here

这样做的结果是标签将像这样剪切文本: 在此处输入图片说明

What comes up in my mind is sizeToFit uses the initial height of the UILabel to determine the max height so in the storyboard I changed this to 250. The result is very strange, the text is placed vertically aligned in the label, like this:

我想到的是sizeToFit是用UILabel的初始高度来决定最大高度的,所以在storyboard中我把这个改成了250。结果很奇怪,文字在label中垂直对齐放置,像这样:

enter image description here

在此处输入图片说明

(I can't show the whole height of the label because the scrollView cuts it off)

(我无法显示标签的整个高度,因为 scrollView 将其切断了)

If I NSLogthe height of the UILabelafter sizeToFit, I properly get to see that the height of the label is 105 pixels but the label is definitely not shown with that height.

如果我NSLogUILabelafter的高度sizeToFit,我会正确地看到标签的高度是 105 像素,但标签绝对没有以该高度显示。

I would highly appreciate some help because this problem is keeping me busy for a week now.

我非常感谢一些帮助,因为这个问题让我忙了一个星期。



Update:Some additional info as requested.

更新:应要求提供一些附加信息。

The code that resizes the UILabelis called after receiving some JSON from the server via RESTkit. viewDidLoadexecutes the function that loads the data via dispatch_async().

UILabel通过 RESTkit 从服务器接收一些 JSON 后调用调整大小的代码。viewDidLoad执行通过 加载数据的函数dispatch_async()

The properties of the label are:

标签的属性是:

Line breaks: word wrap
Autoshrink: Min font size (10)
Tightening letter spacing is off and Autoresize subviewsis turned on.

换行符:自动换行
Autoshrink:最小字体大小 (10)
收紧字母间距已关闭,自动调整子视图大小已打开。

The container that holds the UILabelis the UIScrollView. I autoresize the height of the scrollview aftercalling sizeToFit.

保存 的容器UILabelUIScrollView。调用我自动调整滚动视图的高度sizeToFit

The view mode of the scrollview is set to Scale to Filland Autoresize subviewsis turned on.

滚动视图的视图模式设置为Scale to Fill并打开Autoresize subviews

回答by Nate

There might be a few problems here.

这里可能有一些问题。

  • First of all, when you say this:
  • 首先,当你说这句话时:

I autoresize the height of the scrollview after calling sizeToFit. The view mode of the scrollview is set to Scall to Fill and Autoresize subviews is turned on.

我在调用 sizeToFit 后自动调整滚动视图的高度。滚动视图的视图模式设置为 Scall to Fill 并打开 Autoresize subviews。

that might be a problem. Calling sizeToFitis attempting to resize your labels. But, if you laterresize the scroll view, andyour scroll view is set to Autoresize Subviews, then it might resize the label again. sizeToFitshould be the lastresizing you do on your label.

那可能是个问题。呼叫sizeToFit正在尝试调整您的标签大小。但是,如果您稍后调整滚动视图的大小,并且您的滚动视图设置为Autoresize Subviews,那么它可能会再次调整标签的大小。 sizeToFit应该是您在标签上所做的最后一次调整大小。

  • Also, when you say "autoresize the height of the scrollview", I'm not 100% sure what you mean. What I think you should do is after you get your JSON response, determine how big the size of all your labels are, and then set the scroll view's content size. The framesize (height) of the scroll view should not change.

  • If you read the UILabel documentation, it says:

  • 另外,当您说“自动调整滚动视图的高度”时,我不是 100% 确定您的意思。我认为您应该做的是在获得 JSON 响应后,确定所有标签的大小,然后设置滚动视图的内容大小frame滚动视图的大小(高度)不应改变。

  • 如果您阅读UILabel 文档,它会说:

adjustsFontSizeToFitWidth

Important: If this property is set to YES, it is a programmer error to set the lineBreakMode property to a value that causes text to wrap to another line.

调整FontSizeToFitWidth

重要提示:如果此属性设置为 YES,则将 lineBreakMode 属性设置为导致文本换行到另一行的值是程序员错误。

So, you probably shouldn't be setting that property (Autoshrink), if the label is set to word wrap, too.

因此,如果标签也设置为自动换行,您可能不应该设置该属性 ( Autoshrink)。

Solution

解决方案

Anyway, I know you're using storyboards, but hopefully the code example below can show you how this should work:

无论如何,我知道您正在使用故事板,但希望下面的代码示例可以向您展示这应该如何工作:

- (void)viewDidLoad
{
   [super viewDidLoad];
   // Do any additional setup after loading the view from its nib.
   self.scrollView.autoresizesSubviews = YES;
   self.scrollView.contentMode = UIViewContentModeScaleToFill;

   // simulate a network delay of 4 seconds to fetch JSON
   double delayInSeconds = 4.0;
   dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
   dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
      // we have the "JSON" data
      int dfltLabelHeight = 250;  // will be resized!
      int yPadding = 10;
      int y = yPadding;
      int numLabels = 8;

      for (int i = 0; i < numLabels; i++) {
         UILabel* label = [[UILabel alloc] initWithFrame: CGRectMake(0, y,
                                                                     self.scrollView.frame.size.width, dfltLabelHeight)];
         label.lineBreakMode = NSLineBreakByWordWrapping;
         label.minimumFontSize = 10;
         label.autoresizesSubviews = YES;  // doesn't matter here
         //label.adjustsFontSizeToFitWidth = YES;
         //label.adjustsLetterSpacingToFitWidth = NO;  // this crashes on iOS 6.1
         label.numberOfLines = 0;
         label.text = @"Nam nisi arcu, sodales vitae scelerisque sit amet. Nam nisi arcu, sodales vitae scelerisque sit amet. Nam nisi arcu, sodales vitae scelerisque sit amet.";
         [self.scrollView addSubview: label];
         [label sizeToFit];

         // re-center the label horizontally
         CGRect frame = label.frame;
         frame.origin.x = (self.scrollView.frame.size.width - frame.size.width) / 2;
         label.frame = frame;

         y += yPadding + label.frame.size.height;
      }

      // adjust scroll view's virtual (content) size to fit the labels
      self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width, y);
   });
}

Results

结果

enter image description here

在此处输入图片说明

回答by Sten

  UIFont *myFont = [UIFont systemFontOfSize:12];
  NSString *myText= @"Nam nisi arcu, sodales vitae scelerisque sit amet. Nam nisi arcu, sodales vitae scelerisque sit amet. Nam nisi arcu, sodales vitae scelerisque sit amet.";
  CGSize textSize = [myText sizeWithFont: myFont constrainedToSize:CGSizeMake(280, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
  descriptionLabel.frame = CGRectMake(20, 200, 280, textSize.height);
  descriptionLabel.text = myText;