xcode 如何创建一个基于约束的视图,在 iPhone 5 和 iPhone 4 之间调整大小,与锚操作相当?

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

How do I create a constraints based view that resizes between iPhone 5 and iPhone 4 comparable to Anchor operation?

xcodeinterface-buildernslayoutconstraint

提问by Warren P

The sort of classic Springs and Struts, aka "Anchor and Align", or "Autosizing masks" is the only sort of resize-management I understand. However in XCode 4.6, "autolayout" using constraints as introduced in iOS 6, is the default, and it makes certain simple things harder, while making a whole world of new arrangements possible, once you learn how. (To be clear, some users might only care to get a simple view working without fighting autolayout battles, so a workaround was suggested early on by Matt, of turning off Autolayout, which is reproduced below)

那种经典的 Springs 和 Struts,又名“Anchor and Align”或“Autosizing mask”是我理解的唯一一种调整大小管理。然而,在 XCode 4.6 中,使用 iOS 6 中引入的约束的“自动布局”是默认设置,它使某些简单的事情变得更加困难,同时一旦您学会了如何进行新的安排,就会使整个世界成为可能。 (需要明确的是,一些用户可能只关心在不进行自动布局战斗的情况下获得一个简单的视图,因此马特早期建议了一种解决方法,即关闭自动布局,如下所示)

iOS 6 Layout Constraints, the Interface Builder system of editing constraints, I do not understand.

iOS 6 Layout Constraints,Interface Builder 系统的编辑约束,我不明白。

enter image description here

在此处输入图片说明

Where XCode Interface Builder automatically creates constraints (such as at the edges of the view) it seems to behave in a way I understand.

XCode Interface Builder 自动创建约束(例如在视图的边缘)它似乎以我理解的方式运行。

What I don't understand is why in the .xib shown here, and also available here, why I can't get the green and magenta regions to maintain a constant border (the white area between them) that gets no thicker and no thinner, no matter what happens to the size of the view.

我不明白的是为什么在这里的.xib显示,也可在这里,为什么我不能得到绿色和红色区域保持恒定的边界(它们之间的白色区域)变得不厚,没有更薄,无论视图大小发生什么变化。

That means I need the green area not to resize vertically and only resize horizontally, but it's insisting on anchoring itself to the bottom of the form, and although starting from a new blank nib again, will restore interface builder so it will notice adjacency of the green and magenta views again, once interface builder has gone "stupid" it insists on only defining the green view's bottom edge in terms of its distance from its parent view's bottom edge, and won't (for any amount of fiddling) do otherwise using mere drag and drop operations. I have also experimented with the Pin commands and haven't found a pin command that works.

这意味着我需要绿色区域不要垂直调整大小而只水平调整大小,但它坚持将自己锚定到表单的底部,尽管再次从一个新的空白笔尖开始,将恢复界面构建器,因此它会注意到再次使用绿色和洋红色视图,一旦界面构建器变得“愚蠢”,它就会坚持仅根据与父视图底部边缘的距离来定义绿色视图的底部边缘,并且不会(对于任何数量的摆弄)否则使用仅仅是拖放操作。我还尝试了 Pin 命令,但没有找到有效的 pin 命令。

No amount of fighting with interface builder menus or dragging and dropping seems to be enough, to get it to let go of one of the constraints. I can't figure out what I'm supposed to do. Delete a constraint? How? Constraints can't be deleted at all as far as I can see, either from the IB Objects pane or from the Utilities -> Size inspector. There is a delete option but it's grayed out in the drop down menu that appears when you click the "gear" icon button in the constraints area.

没有多少与界面构建器菜单或拖放的斗争似乎就足够了,让它摆脱其中的一个限制。我不知道我应该做什么。删除约束?如何?就我所见,无论是从 IB 对象窗格还是从实用程序 -> 大小检查器,都无法删除约束。有一个删除选项,但是当您单击约束区域中的“齿轮”图标按钮时,它会在出现的下拉菜单中变灰。

Ideally I'd love it if the green area resized as the view gets wider, but not as it gets taller or shorter. I thought this was obvious in every other tool, but in XCode+Autolayout, it's either not resize at all, or resize in all four directions. I can't delete or remove the constraints that are doing things I don't want to do. Do you have to have four constraints on each view that is inside another view?

理想情况下,如果绿色区域随着视野变宽而调整大小,而不是随着它变高或变短,我会喜欢它。我认为这在所有其他工具中都很明显,但是在 XCode+Autolayout 中,它要么根本不调整大小,要么在所有四个方向上调整大小。我无法删除或移除正在做我不想做的事情的约束。您是否必须对另一个视图内的每个视图有四个约束?

(Update 1: You can not remove any constraint that would result in an ambiguous or unspecified layout.)

(更新 1:您不能删除任何会导致不明确或未指定布局的约束。)

(Update 2: Sometimes if a uiview pane won't snap to a sibling, deleting that uiview and trying again will allow it to naturally "snap" to a sibling, and the constraint will be made relative to a sibling view object instead of a parent.)

(更新 2:有时如果 uiview 窗格不会与兄弟视图对齐,删除该 uiview 并重试将允许它自然地“对齐”到兄弟视图,并且约束将相对于兄弟视图对象而不是父母。)

(Update 3: Matt deleted his workaround, I've reproduced it below.)

(更新 3:马特删除了他的解决方法,我在下面复制了它。)

Workaround for people who didn't want Autolayout in the first place, and who just wanted the old springs and struts back:

对于一开始不想要 Autolayout 并且只想要旧的弹簧和支柱的人的解决方法:

Step 1: Turn Off Autolayout:

第 1 步:关闭自动布局:

enter image description here

在此处输入图片说明

Step 2: Select the Correct Autoresizing Masks:

步骤 2:选择正确的自动调整大小蒙版:

enter image description here

在此处输入图片说明

采纳答案by jrturton

The key to editing constraints in interface builder is never to drag and drop anything once you've added it to the view. Move and arrange things by editing the constraints instead. Use the pinning menu to create new constraints. You can delete unwanted constraints once you've added sufficient new ones to unambiguously replace the automatically added system constraints.

在界面构建器中编辑约束的关键是永远不要在将任何内容添加到视图后进行拖放。通过编辑约束来移动和排列事物。使用固定菜单创建新的约束。添加足够的新约束以明确替换自动添加的系统约束后,您可以删除不需要的约束。

In your case I created the following constraints:

在您的情况下,我创建了以下约束:

enter image description here

在此处输入图片说明

I renamed your views "Green" and "Magenta" to make things clearer in the document navigator. What I have done is:

我将您的视图重命名为“绿色”和“洋红色”,以使文档导航器中的内容更清晰。我所做的是:

  • Pin the vertical spacing between the views
  • Pinned each view to the left and right sides
  • Pinned the top view to a set height and a set distance from the top of the superview
  • Pinned the bottom of the bottom view to the bottom of the superview.
  • 固定视图之间的垂直间距
  • 将每个视图固定到左侧和右侧
  • 将顶视图固定到与超级视图顶部的设定高度和设定距离
  • 将底视图的底部固定到超级视图的底部。

This gives you the layout you want, I think. I have written in excruciating detail about this here, if you want to read more.

我想,这为您提供了您想要的布局。如果你想阅读更多,我在这里写了关于这个的令人难以忍受的细节。

回答by Warren P

This is the answer if you don't want to turn off the new iOS6 Auto Layout mode.

如果您不想关闭新的 iOS6 自动布局模式,这就是答案。

If the view mode for the top level view and all the sub-level views is Scale to Fill, you use the anchor mode "less than or equal" in this case, because you can't delete this constraint. The two colored views are not stored in the nib as having a size (width,height) or position (top left corner) instead they are stored with constraints representing their layout. The layout "less than or equal" instead of "equal" can be accessed by clicking on the upper square, then four constraint lines appear, select the bottom one which goes from the lower edge of the control you've selected to the bottom of the view, and change the type from Equal to Less than or Equal.

如果顶层视图和所有子级视图的视图模式是缩放填充,则在这种情况下使用锚点模式“小于或等于”,因为您无法删除此约束。两个彩色视图没有存储在笔尖中,因为它们具有大小(宽度、高度)或位置(左上角),而是与表示其布局的约束一起存储。单击上方的方块可以访问“小于或等于”而不是“等于”的布局,然后出现四条约束线,选择底部一条从您选择的控件的下边缘到底部的视图,并将类型从等于更改为小于或等于。

enter image description here

在此处输入图片说明

If the view mode is NOT Scale to fill, other constraint changes would be required. This multi-faceted design is more flexible than the old "springs and struts" but is not exactly as simple to learn.

如果视图模式不是按比例填充,则需要更改其他约束。这种多面设计比旧的“弹簧和支柱”更灵活,但并不那么容易学习。

The more obvious mode you could use is to get a constraint in between two objects. Why this is so difficult (sometimes I can do this and sometimes i can't) I still don't know.

您可以使用的更明显的模式是在两个对象之间获得约束。为什么这如此困难(有时我可以这样做,有时我不能)我仍然不知道。

Here's a sample when I was able to get a constraint to appear between two objects instead of from that object to its parent view, but this situation, were I able to always get Interface Builder to co-operate would be a far more intuitive way of creating a situation where the top square is not anchored to the whole view's height:

这是一个示例,当我能够让约束出现在两个对象之间而不是从该对象到其父视图时,但在这种情况下,我是否能够始终让 Interface Builder 合作将是一种更直观的方式创建顶部方块未锚定到整个视图的高度的情况:

enter image description here

在此处输入图片说明

If the upper color view has an anchor to the view below it, this absolutely means that the reverse constraint cannot be against the same view, or else an ambiguity or "circular reasoning" situation would exist. Thus, we can have A depend on B, but not B simultaneously depend on A. So in that case, the constraint is switched to depend on the absolute height or width of the view. In this particular case that I have found, considerable trial and error seems to be required to recreate what could previously have been done incredibly intuitively before it was improved.

如果上面的彩色视图有一个指向它下面的视图的锚点,这绝对意味着反向约束不能针对同一个视图,否则就会出现歧义或“循环推理”的情况。因此,我们可以让 A 依赖于 B,但不能同时依赖于 A。所以在这种情况下,约束切换为依赖于视图的绝对高度或宽度。在我发现的这个特殊情况下,似乎需要大量的反复试验才能重新创建以前可以在改进之前非常直观地完成的工作。

Finally, I find that the instructions above will appear to not work when you end up with extra constraints, which get magically added when you least expect them. Very subtly, you should see two lines instead of one, like this:

最后,我发现当您最终遇到额外的约束时,上面的说明似乎不起作用,而在您最不期望它们时会神奇地添加这些约束。非常巧妙的是,您应该看到两行而不是一行,如下所示:

enter image description here

在此处输入图片说明

I am able to get Interface Builder to keep adding more and more duplicate constraints just by changing a constraint from Equals to Less than or Equal. I believe that's a bug in interface builder in XCode 4.6, and since layout contraints are a relatively new part of CococaTouch, I'm not surprised that the Interface builder support for auto-creating constraints as you drag and move items around, is buggy.

只需将约束从等于更改为小于或等于,我就能够让 Interface Builder 不断添加越来越多的重复约束。我相信这是 XCode 4.6 中界面构建器中的一个错误,并且由于布局约束是 CococaTouch 的一个相对较新的部分,我并不惊讶界面构建器支持在您拖动和移动项目时自动创建约束是有问题的。