xcode iOS 对等宽/高度按钮网格的约束导致定位和大小发生变化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25779201/
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 05:31:38  来源:igfitidea点击:

iOS Constraints on Grid of Equal Width/Height Buttons cause positioning and size to vary

iosxcodeuistoryboardnslayoutconstraint

提问by Kenny Wyland

I'm updating my Calculator app to use new dynamically sized buttons and having a problem with the constraints. The contains should work fine as far as I can tell, but Xcode complains about misplaced views. The values it gives for the misplaced views are not proper and if I try to fix them, then it just causes more views to be "misplaced."

我正在更新我的计算器应用程序以使用新的动态大小的按钮,并且在约束方面遇到了问题。据我所知,包含应该可以正常工作,但 Xcode 抱怨视图错位。它为错位的视图提供的值是不正确的,如果我尝试修复它们,那么它只会导致更多的视图“错位”。

In the screenshot below, the first multi-colored row (orange, green, pink, yellow, red) is a row of UILabels. They should all have equal widths with 0 spacing between them and the edges of the screen. They are in a container view (Xcode label is "Register Label View", shown in a screenshot below that one.) The Register Label View container has a fixed height constraint.

在下面的截图中,第一个多色行(橙色、绿色、粉色、黄色、红色)是一行 UILabels。它们都应该具有相等的宽度,它们与屏幕边缘之间的间距为 0。它们位于容器视图中(Xcode 标签是“注册标签视图”,如下面的屏幕截图所示。)注册标签视图容器具有固定的高度约束。

Then below that, is another container view ("Keypad View") and inside that is a 5x8 grid of views (the buttons on my calculator). The buttons should all have the same widths and all have the same heights. In my storyboard, they are 64x58 which fits perfectly within my 320x464 Keypad View. (320/5 = 64, and 464/8=58).

然后在它下面是另一个容器视图(“键盘视图”),里面是一个 5x8 的视图网​​格(我的计算器上的按钮)。按钮的宽度和高度都应该相同。在我的故事板中,它们是 64x58,非常适合我的 320x464 键盘视图。(320/5 = 64,464/8 = 58)。

enter image description here

在此处输入图片说明

Below is a screenshot of the Storyboard warnings. Notice the last two items are Dynamic Buttons (in the Keypad View) and it says that one of them is expected to be 63 wide and the other is expected to be 65 wide. That's not correct. They are all supposed to be 64 wide and they all have an Equal Widths constraint.

下面是 Storyboard 警告的屏幕截图。请注意,最后两项是动态按钮(在键盘视图中),它表示其中一个预计为 63 宽,另一个预计为 65 宽。那不正确。它们都应该是 64 宽,并且都具有等宽约束。

One of the labels also seems to have the same problem where Xcode expects one of them to be 63 wide, but they should all be 64 wide.

其中一个标签似乎也有同样的问题,其中 Xcode 预计其中一个是 63 宽,但它们都应该是 64 宽。

enter image description here

在此处输入图片说明

You can see in the Storyboard that the buttons all line up nicely without overlapping (based on their frames), but when I run it in the Simulator, you can see them overlapping each other by one pixel in different directions on each row:

您可以在 Storyboard 中看到所有按钮都很好地排列而没有重叠(基于它们的框架),但是当我在模拟器中运行它时,您可以看到它们在每一行的不同方向上相互重叠一个像素:

enter image description here

在此处输入图片说明

The way I set up the constraints: I arranged them all using their frame (x,y,w,h) in the storyboard, then I selected them all, and added constraints like this:

我设置约束的方式:我使用情节提要中的框架 (x,y,w,h) 将它们全部排列,然后全部选中,并添加如下约束:

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

But then it immediately complains that several of the items are misplaced. What am I doing wrong? How can I make this work properly?

但随后它立即抱怨说有几件物品放错了地方。我究竟做错了什么?我怎样才能使它正常工作?

采纳答案by Kenny Wyland

Ok, I figured out how to make it work with only constraints. There were just too many interconnected dependencies and the system couldn't handle it. I was selecting the entire grid of buttons and adding Equal Heights and Equal Widths constraints to all of them, which meant each button was dependent upon every other button.

好的,我想出了如何让它只在约束下工作。相互关联的依赖关系太多,系统无法处理。我选择了整个按钮网格并向所有按钮添加等高和等宽约束,这意味着每个按钮都依赖于其他每个按钮。

Instead, I did it row by row. I selected one row:

相反,我是一行一行地做的。我选择了一行:

enter image description here

在此处输入图片说明

I applied the Equal Heights and Equal Widths constraints to each item in that row. Then I did the same to Row 2, then Row 3, etc. So, each row was depending only on itself. However, those constraints weren't enough to define the UI completely, because the Height was still undefined.

我对该行中的每个项目应用了等高和等宽约束。然后我对第 2 行,然后是第 3 行等做了同样的事情。所以,每一行都只取决于它自己。但是,这些约束还不足以完全定义 UI,因为 Height 仍未定义。

So, then I selected the first column (i.e. first item in each row) and applied Equal Widths and Equal Heights constraints to those items. Then all of the constraints behaved properly and I didn't receive any Misplaced Views warnings.

所以,然后我选择了第一列(即每行中的第一个项目)并对这些项目应用等宽和等高约束。然后所有约束都正常运行,我没有收到任何错误放置的视图警告。

I believe this worked because the constraints on the columns could resolve the Height of each row and then row could resolve it's own Widths without having to interact with any other row.

我相信这是有效的,因为列上的约束可以解析每行的高度,然后行可以解析它自己的宽度,而无需与任何其他行交互。

回答by rdelmar

The small amount of code below (and setting the cell size and minimum spacings in the storyboard) will give you your keyboard using a collection view.

下面的少量代码(并在故事板中设置单元格大小和最小间距)将为您提供使用集合视图的键盘。

@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;
}

This gives the following result,

这给出了以下结果,

enter image description here

在此处输入图片说明