iOS 对等宽/高按钮网格的约束导致位置和大小发生变化
Posted
技术标签:
【中文标题】iOS 对等宽/高按钮网格的约束导致位置和大小发生变化【英文标题】:iOS Constraints on Grid of Equal Width/Height Buttons cause positioning and size to vary 【发布时间】:2014-09-11 04:39:06 【问题描述】:我正在更新我的计算器应用程序以使用新的动态大小的按钮,并且遇到了约束问题。据我所知,包含应该可以正常工作,但是 Xcode 抱怨视图放错了位置。它为错位的视图提供的值不正确,如果我尝试修复它们,那么它只会导致更多的视图被“错位”。
在下面的截图中,第一个多色行(橙色、绿色、粉色、黄色、红色)是一行 UILabel。它们都应该具有相等的宽度,它们与屏幕边缘之间的间距为 0。它们位于容器视图中(Xcode 标签是“Register Label View”,如下面的屏幕截图所示。)Register Label View 容器具有固定的高度约束。
然后在其下方是另一个容器视图(“键盘视图”),内部是一个 5x8 的视图网格(我的计算器上的按钮)。按钮应该都具有相同的宽度和高度。在我的故事板中,它们是 64x58,非常适合我的 320x464 键盘视图。 (320/5 = 64,464/8=58)。
以下是情节提要警告的屏幕截图。请注意最后两项是动态按钮(在键盘视图中),其中一项预计为 63 宽,另一项预计为 65 宽。这是不正确的。它们都应该是 64 宽,并且都具有 Equal Widths 约束。
其中一个标签似乎也有同样的问题,Xcode 期望其中一个是 63 宽,但它们都应该是 64 宽。
您可以在情节提要中看到所有按钮都很好地排列而没有重叠(基于它们的帧),但是当我在模拟器中运行它时,您可以看到它们在每一行的不同方向上相互重叠一个像素:
我设置约束的方式:我在情节提要中使用它们的框架 (x,y,w,h) 将它们全部排列,然后我将它们全部选中,并添加如下约束:
但随后它立即抱怨有几件物品放错了位置。我究竟做错了什么?我怎样才能使它正常工作?
【问题讨论】:
使用自动布局处理多个视图可能会很痛苦。我要么在代码中制作你的按钮,不使用约束,要么为键盘使用集合视图——在这种情况下,所有的对齐工作都会为你完成。 要确保约束是正确的,您必须逐个视图从上到下尝试。当我贪婪时,XCode 总是抱怨。当我遇到像你这样的问题时,我总是会清除所有限制并重新开始。 顺便说一句,我看到你的故事板中看起来像倒转;如果是这样(从右侧出来的线循环到计算器视图的左侧),那不是一件好事。 @rdelmar 我相信这是一个“解雇”转场的实验。见这里:jeffreysambells.com/2014/02/19/… 【参考方案1】:好的,我想出了如何让它只在约束条件下工作。相互关联的依赖关系太多,系统无法处理。我选择了整个按钮网格并向所有按钮添加等高和等宽约束,这意味着每个按钮都依赖于其他所有按钮。
相反,我是逐行进行的。我选择了一行:
我对该行中的每个项目应用了等高和等宽约束。然后我对第 2 行、第 3 行等做了同样的事情。所以,每一行都只取决于它自己。但是,这些约束还不足以完全定义 UI,因为高度仍未定义。
所以,然后我选择了第一列(即每行中的第一项)并将等宽和等高约束应用于这些项。然后所有约束都正常运行,我没有收到任何错位视图警告。
我相信这行得通,因为列上的约束可以解决每一行的高度,然后行可以解决它自己的宽度,而无需与任何其他行交互。
【讨论】:
【参考方案2】:下面的少量代码(并在情节提要中设置单元格大小和最小间距)将为您提供使用集合视图的键盘。
@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
@end
@implementation ViewController
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
return 40;
-(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
cell.contentView.backgroundColor = (indexPath.row % 2 == 0)? [UIColor colorWithRed:180/255.0 green:210/255.0 blue:254/255.0 alpha:1] : [UIColor colorWithRed:50/255.0 green:167/255.0 blue:85/255.0 alpha:1];
return cell;
这给出了以下结果,
【讨论】:
如果 UI 最终变宽(例如 iPhone 6 Plus),这不会导致显示额外的列吗?似乎很奇怪,我需要将我的代码完全重写为按需 UICollectionView 来做一些约束似乎是理想设计的事情。 :// @KennyWyland,当然,如果您支持多个宽度的屏幕,您必须考虑视图的宽度。这可以通过将代码中的项目大小设置为 width/5 来轻松完成。我在尝试对许多视图设置约束时遇到了同样的问题,所以我不会说它们是“理想地”为这个特定目的而设计的。 我想出了一种方法让它在没有警告的情况下工作。看起来它有太多相互关联的约束,所以我分两个阶段进行。以上是关于iOS 对等宽/高按钮网格的约束导致位置和大小发生变化的主要内容,如果未能解决你的问题,请参考以下文章