具有自动布局的 UITableView 中的动态列
Posted
技术标签:
【中文标题】具有自动布局的 UITableView 中的动态列【英文标题】:Dynamic Columns in a UITableView with Auto Layout 【发布时间】:2013-10-15 19:06:21 【问题描述】:在我的 iPad 应用程序中,我将有一个 UITableView
显示在弹出窗口中。我有多个要显示的值,因此我制作了一个带有多个标签的自定义UITableViewCell
,以模拟表格中的许多“列”。我想做的是确保我所有的“列”都排成一行。
问题是,我无法对列的宽度进行硬编码,因为我正在从 XML Web 服务动态填充数据 - 所以在我进行调用之前我不知道它们需要多宽并且收到数据。
我的想法是遍历数据(一旦我得到它),并使用NSString
的sizeWithAttributs:
方法来获取我的每一列的最大宽度。然后我会将该宽度发送到我的自定义单元格,以便该单元格可以在其layoutSubviews
方法中使用它。问题是,我正在尝试使用NSLayoutConstraints
来完成所有这些工作,并且在我看到的所有示例中,constraintsWithVisualFormat:
中的任何尺寸都是硬编码的——直到运行时我才知道我的尺寸是多少。我的想法是做类似的事情
NSDictionary *myDictionary = NSDictionaryOfVariableBindings(myLabel1,myLabel2)
NSArray *myConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[myLabel1(%d)]-[myLabel2(%d)]",myWidth1,myWidth2 options:NSLayoutFormatAlignAllBaseline metrics:nil views:myDictionary];
但这会导致构建错误。是否可以在运行时动态地为constraintsWithVisualFormat
提供大小,而不是硬编码?
【问题讨论】:
【参考方案1】:推荐的做法是使用metrics
参数:
NSDictionary *myDictionary = NSDictionaryOfVariableBindings(myLabel1,myLabel2)
NSArray *myConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-[myLabel1(lbl1w)]-[myLabel2(lbl2w)]"
options:NSLayoutFormatAlignAllBaseline
metrics:@@"lbl1w": @(myWidth1),
@"lbl2w": @(myWidth2)
views:myDictionary];
这基本上允许您提供将名称映射到数值的字典,以便在可视格式字符串中的任何位置使用。这些值需要是 NSNumber
实例,可以使用去年引入的 @(aVariable)
构造从 C 数值变量轻松构造。
【讨论】:
是否有特别的原因推荐这种方式,而不是使用我的方式?使用这些指标对我来说似乎并不简单(我认为它更复杂)。此外,我不记得看到metrics
字典用于将值链接到临时变量,只是为了在另一个参数中使用,但我看到了大量传递 [NSString stringWithFormat:@"..."]
而不仅仅是 @"..."
的实例当 NSString
被请求作为输入类型时。我想我只是有点困惑,为什么约束应该以不同的方式完成。
本身并不推荐使用字符串格式。由于自动布局的可视格式解析器无论如何都会进行字符串解析工作,您不妨告诉它用一些名称替换它们的数值。您的方式使字符串解析发生两次。此外,实际名称总是比一堆%d
更具可读性。最后,如果您要多次重复使用相同的值,这种方式将证明自己很方便。
此外,如果您要重用具有不同宽度或边距的视觉格式,或者跨视觉格式重用一组宽度/边距,则会更简洁。值得一试!【参考方案2】:
在我写这篇文章的时候,我有一种不愚蠢的想法,这促使我看看你实际上应该将什么作为constraintsWithVisualFormat
的第一个参数传递给constraintsWithVisualFormat
,果然,它只是在寻找一个@ 987654322@。所以解决办法就是简单的把前面的字符串打断:
NSString *formattedString = [NSString stringWithFormat:@"H:|-[myLabel1(%d)]-[myLabel2(%d)]",myWidth1,myWidth2];
然后传入:
NSArray *myConstraints = [NSLayoutConstraint constraintsWithVisualFormat:formattedString options:NSLayoutFormatAlignAllBaseline metrics:nil views:myDictionary];
我还没有测试过这个(我仍然需要编写很多代码来循环数据和所有这些),但它应该可以工作。正如我所说,我看到的所有示例都对尺寸进行了硬编码,所以我想我会发布这个,以防其他人来寻找如何做到这一点,或者以防我稍后忘记=)。
【讨论】:
以上是关于具有自动布局的 UITableView 中的动态列的主要内容,如果未能解决你的问题,请参考以下文章
使用自动布局的 UITableView 中的动态 UITextView 高度?
自动布局动态大小 uitableview 单元格的最佳方法是啥
在 UITableView 中使用自动布局进行动态单元格布局和可变行高