草庐IT

ios - 如何以编程方式添加具有可变高度和布局 ios 的 UILabel

coder 2024-01-16 原文

我一直在搜索一整天,但没能成功。

我有一个 UIView,它有两个标签,一个在另一个上方,在左侧,一个按钮在右侧。我添加了约束,让 autolayout 相应地调整 View 大小。当我为 UIView 的高度设置一个约束(并且没有为两个 UILabel 的高度设置任何约束)时,一切都运行良好,但是作为较低的 UILabel 会有所不同,我删除了该约束并为 UILabel 设置了两个约束,一个固定用于较高的 UILabel ,另一个与关系“更大” than or equal”用于下部 UILabel,另一个用于固定下部 UILabelUIView 之间的距离。

看起来自动布局无法计算下部 UILabelintrinsicContentSize,因为它永远不会将其高度增加到 10px 以上,尽管下部 UILabel

UIView *miView = [[UIView alloc] init];
UILabel *miLabel = [[UILabel alloc] init];
[miLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[miDetailsLabel setNumberOfLines:1];
[miDetailsLabel setText:@"Just one line."];
[miView addSubview:miLabel];
UILabel *miDetailsLabel = [[UILabel alloc] init];
[miDetailsLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[miDetailsLabel setNumberOfLines:0];
[miDetailsLabel setText:@"Enough text to show 3 lines on an IP4, except first of three UILabels on my test code, with no content"];
[miView addSubview:miDetailsLabel];
UIButton *miButton = [[UIButton alloc] init];
[miButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[miView addSubview:miButton];

NSArray *constraint_inner_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[label]-(10)-[button(52)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"button":miButton}];
NSArray *constraint_inner2_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[details]-(10)-[button]-(0)-|" options:0 metrics:nil views:@{@"details":miDetailsLabel, @"button":miButton}];
NSArray *constraint_label_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[label(18)]-(2)-[details(>=10)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"details":miDetailsLabel}];
NSArray *constraint_button_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button(22)]" options:0 metrics:nil views:@{@"button":miButton}];
[miView addConstraint:[NSLayoutConstraint constraintWithItem:miButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:miView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[miView addConstraints:constraint_inner_h];
[miView addConstraints:constraint_inner2_h];
[miView addConstraints:constraint_label_v];
[miView addConstraints:constraint_button_v];

我放了一个简化版的代码。

对我遗漏了什么有什么想法吗?

谢谢

更新:感谢 Matt 的建议,我已经尝试使用此解决方案将正确的值设置为 preferredMawLayoutWidth:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    NSArray *allKeys = [dictOpcionesTickets allKeys];
    for (NSString *key in allKeys) {
        NSArray *tmpArray = [dictOpcionesTickets objectForKey:key];
        if (![[tmpArray objectAtIndex:0] isEqual:@""]) {
            UILabel *tmpLabel = [tmpArray objectAtIndex:3];
            tmpLabel.preferredMaxLayoutWidth = tmpLabel.frame.size.width;
            NSLog(@"width: %f",tmpLabel.frame.size.width);
        }
    }
    [self.view layoutIfNeeded];
}

为了解释代码,正如我所说,我正在动态地执行它,所以我创建了一个字典,其中包含一个数组,其中包含对我的 UILabel 的引用(以及其他有趣的信息)。当我运行代码时,我得到下一条日志(代码解析 3 UILabel,第一个没有内容的标签):

2014-12-28 20:40:42.898 myapp[5419:60b] width: 0.000000
2014-12-28 20:40:42.912 myapp[5419:60b] width: 0.000000
2014-12-28 20:40:43.078 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.080 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.326 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.327 myapp[5419:60b] width: 229.000000

但我仍然得到相同的结果...UIView 仍然显示高度等于约束设置的最小高度,而不是显示 UILabel 的内容。

更新 2 还在胡闹。

我已经测试了我的初始代码,但在 xcode 6 中的一个新项目上进行了简化,该项目在装有 iOS7 的实际 iPhone 4 上运行,并且无需设置 preferredMaxLayoutWidth 或子类化 UILabel<>,甚至不在父 View 上调用 layoutIfNeeded。但是当涉及到真正的项目时(我认为它最初是在 xcode 4 或 5 中构建的)它不起作用:

- (void)addLabelsDinamically {
    self.labelFixed.text = @"Below this IB label goes others added dinamically...";

    UIButton *miBoton = [[UIButton alloc] init];
    miBoton.translatesAutoresizingMaskIntoConstraints = NO;
    [miBoton setTitle:@"Hola" forState:UIControlStateNormal];
    [self.viewLabels addSubview:miBoton];
    [self.viewLabels addConstraint:[NSLayoutConstraint constraintWithItem:miBoton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.viewLabels attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[boton(22)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[boton(40)]" options:0 metrics:nil views:@{@"boton":miBoton}]];

    UILabel *miLabel = [[UILabel alloc] init];
    miLabel.translatesAutoresizingMaskIntoConstraints = NO;
    miLabel.backgroundColor = [UIColor redColor];
    miLabel.numberOfLines = 0;
    miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
    [self.viewLabels addSubview:miLabel];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":self.labelFixed}]];
    UIView *pre = miLabel;

    miLabel = [[UILabel alloc] init];
    miLabel.translatesAutoresizingMaskIntoConstraints = NO;
    miLabel.backgroundColor = [UIColor greenColor];
    miLabel.numberOfLines = 0;
    miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
    [self.viewLabels addSubview:miLabel];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]];
}

啊,在同一屏幕上,我在 IB 上添加了一个 UILabelnumberOfLines 设置为“0”,垂直约束“大于或等于”,水平约束以类似的方式设置(但两个约束都设置在 IB 上)......并且它完美地工作......这让我发疯!有帮助吗???

最佳答案

好吧,我终于找到了错误,正如我在“UPDATE 2”中所说的那样,很奇怪它正在处理通过 IB 添加的 UILabel,而不是那些添加的动态地。

所以,我再次查看 IB 上的屏幕,发现我有一个“等于”关系的高度限制,当我将其更改为“大于或等于”时,一切都开始起作用了!!!!为什么我没有注意到约束不是“大于或等于”?因为随着我在内部添加带有标签的 View ,带有约束的 View 变得越来越大。这是一个错误吗?

好吧,总结一下是否有人觉得这有用。 “如何添加适应其内容的UILabel多行?”

iOS 6 版本中,这是“preferredMaxLayoutWidth”的错误,一旦“布局”就无法获得宽度,因此程序员必须设置它通过代码(最好的解决方案是动态地进行,我把它放在上面的问题中的一个例子)。

幸运的是,在 iOS7 和更高版本上,这个问题已经解决了,您只能依赖约束。

  1. 通过IB添加

    • 添加 UILabel,并将“行数”设置为“0”(这将使 UILabel 使用所需的行数)。
    • 添加约束条件,您至少需要 3 个约束条件(固定到顶部或底部,以及两侧),第四个是具有“大于或等于”关系的高度。
    • 确保 View 容器有足够的空间,或者还具有“大于或等于”关系的高度限制。
  2. 通过代码添加(只需粘贴上面发布的代码):

    UILabel *miLabel = [[UILabel alloc] init]; // Initialitze the UILabel
    miLabel.translatesAutoresizingMaskIntoConstraints = NO;  // Mandatory to disable old way of positioning
    miLabel.backgroundColor = [UIColor redColor];
    miLabel.numberOfLines = 0;  // Mandatory to allow multiline behaviour
    miLabel.text = @"ñkhnaergñsdbmnñgwn"; // big test to test
    [self.viewLabels addSubview:miLabel];  // Add subview to the parent view
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[label]-(10)-|" options:0 metrics:nil views:@{@"label":miLabel}]];  // horizontal constraint
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[label]" options:0 metrics:nil views:@{@"label":miLabel}]];
    UIView *pre = miLabel;
    
    // Adding a second label to test the separation
    miLabel = [[UILabel alloc] init];
    miLabel.translatesAutoresizingMaskIntoConstraints = NO;
    miLabel.backgroundColor = [UIColor greenColor];
    miLabel.numberOfLines = 0;
    miLabel.text = @"ñkhnaermgñlkafmbnoetñnngñsdbmnñgwn";
    [self.viewLabels addSubview:miLabel];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[label]-(10)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(10)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]];
    

感谢那些试图帮助我的人!!这个网站太棒了:)

关于ios - 如何以编程方式添加具有可变高度和布局 ios 的 UILabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27678850/

有关ios - 如何以编程方式添加具有可变高度和布局 ios 的 UILabel的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  6. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  9. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  10. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

随机推荐