动态数量的视图的自动布局
Posted
技术标签:
【中文标题】动态数量的视图的自动布局【英文标题】:AutoLayout for a Dynamic number of Views 【发布时间】:2014-01-09 15:47:35 【问题描述】:我在UIViewController
的底部有一个UIView
,可以添加不同数量的视图。
NSUInteger letterCount = [word length];
NSLog(@"The word letter count is: %ld",(unsigned long)letterCount);
for (int i = 0; i < letterCount; i++)
NSLog(@"new view being created");
UIView *letterTileView = [UIView autolayoutView];
letterTileView.tag = 600 + i;
[self.bottomBarView addSubview:letterTileView];
单词可以是任何单词,因此有不同数量的字母。如果单词是 APPLE,它将在底部栏视图中创建 5 个子视图。
我想使用自动布局来布局这些视图。每个视图应为 48x48(高 x 宽)。我希望这些子视图在底部栏视图中居中并在它们之间有填充。
我之前使用以下方法设置 AL,但不确定如何处理动态情况并正确布局。
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views
【问题讨论】:
在代码中添加约束是一件常见且简单的事情。事实上,Apple 提供了示例代码来展示如何做到这一点(在与您描述的情况非常相似的情况下)。您到底遇到了什么问题? 你能分享他们提供的例子吗? Auto Layout 的文档实际上非常有限。我遇到的问题是我正在尝试布局动态数量的视图,例如 |-[view1]-[view2]-[view3]-|。但不确定如何在视图创建期间构建约束 观看关于自动布局的 WWDC 2012 视频以及与之相关的可下载代码。有一个游戏的字母砖排成一排,和你描述的非常相似。 【参考方案1】:这是我书中的一个示例,我在其中以编程方式生成一堆 UILabel 并在执行过程中为它们添加约束。这与您的情况不同(我的标签是垂直排列的),但它显示了在动态创建界面时添加约束是多么容易:
UILabel* previousLab = nil;
for (int i=0; i<30; i++)
UILabel* lab = [UILabel new];
// lab.backgroundColor = [UIColor redColor];
lab.translatesAutoresizingMaskIntoConstraints = NO;
lab.text = [NSString stringWithFormat:@"This is label %d", i+1];
[v addSubview:lab];
[v addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[lab]"
options:0 metrics:nil
views:@@"lab":lab]];
if (!previousLab) // first one, pin to top
[v addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[lab]"
options:0 metrics:nil
views:@@"lab":lab]];
else // all others, pin to previous
[v addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[prev]-(10)-[lab]"
options:0 metrics:nil
views:@@"lab":lab, @"prev":previousLab]];
previousLab = lab;
【讨论】:
谢谢@matt - 我能够使用与您上面的答案类似的方法。它还在 [previousView] 循环之后添加另一个约束到超级视图。感谢您的帮助 一直在寻找这样的解决方案。然而,我在一个视图中有一组字段(如带有标签和输入的表单)作为单行。所有其他行都将低于此值。非常感谢@matt【参考方案2】:我过去所做的是根据您将拥有的视图数量动态创建可视格式字符串。一些示例代码:
NSArray *views = @[view1, view2, view3]; // this would be a dynamic array with views
NSMutableString *vflString = [NSMutableString string];
NSMutableDictionary *viewsDictionary = [NSMutableDictionary dictionary];
for (int i = 0; i < [views count]; i++)
NSString *viewIdentifier = [NSString stringWithFormat:@"view%d", i];
[vflString appendString:[NSString stringWithFormat:@"-[%@]-", viewIdentifier];
viewsDictionary[viewIdentifier] = views[i];
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vflString options:0 metrics:nil views:viewsDictionary];
[self.view addConstraints:constraints];
当然,您也可以更改指标和定位等。
【讨论】:
这对我不起作用,因为您将 viewIdentifier 传递给 vflString,但这只是一个创建的字符串,而不是指向视图的指针的实际名称。如何动态创建指向我的新视图的指针名称,以便在我的示例中正确传递名称? @StuartM 看看@Scott 向您展示了什么。viewsDictionary
是指向新视图的“指针”。
@StuartM:指向视图的变量的实际名称无关紧要。在许多情况下,使用NSDictionaryMakeWithVariableBindings()
有助于使键和视图之间的链接变得容易,但您没有 使用它。以上是关于动态数量的视图的自动布局的主要内容,如果未能解决你的问题,请参考以下文章