【问题标题】:How to adjust views using auto layout?如何使用自动布局调整视图?
【发布时间】:2013-07-18 07:54:40
【问题描述】:

我在我的示例应用程序中使用 AutoLayout。我有三个视图,topView、middleView、bottomView。以下是我需要的约束,

顶视图:

  1. 始终从 x 原点 10 开始。
  2. 左右边距 10.
  3. 高度应根据屏幕边界(或超级视图)而有所不同。

中间视图:

  1. 顶视图和中间视图之间应该有 10 px 的垂直边距。
  2. 左右边距 10.
  3. 高度应根据屏幕边界(或超级视图)而有所不同。

底部视图:

  1. 中间视图和底部视图之间应该有 10 px 的垂直边距。
  2. 左右边距 10.
  3. 高度应保持不变,例如 30。

我希望根据设备屏幕尺寸,底部视图 y 原点应该改变,以便调整中间和顶部视图尺寸。 这里的问题是没有办法找出,底视图和界面的 y 原点应该是什么提供了永久约束,例如:

  1. 中间视图超级视图的顶部空间。
  2. 顶部空间用于超级视图以用于底部视图。

这是因为没有办法找出视图的高度。 唯一的困难是确定顶视图和中间视图的高度。

【问题讨论】:

  • 您遇到的问题是顶部和中间的高度(因此底部的位置)不明确。你希望他们如何工作?这些是什么类型的视图?它们的高度如何工作?高度是否取决于它们的内容?等等......另外,它们是什么类型的视图? UITextViews,UIImageViews?也许他们的工作方式是...... middleView 高度等于 topView 高度除以 2?或者类似的东西。不过,您需要以某种方式定义高度。
  • 自动布局的美妙之处在于它是描述性的:你描述你想要什么,系统负责计算。但是,您需要描述您希望系统如何调整顶视图和中间视图的高度。 “高度应该变化”并不是系统可以使用的真正描述。您为什么不尝试向我们描述您的意图,我们可以帮助您向系统描述它? (例如,中间视图应该是顶视图高度的一半。)
  • @Maarten 你说的比我想的要好得多:) 向我们描述你希望它们如何工作,我们将尝试找出哪些约束会产生这种效果。
  • 顶视图和中间视图之间没有关系,所以我无法用言语表达。我只是想要那个,我有三个位置固定的视图,最后一个视图高度是固定的。其他两个视图高度将根据设备屏幕尺寸而有所不同。所以无论我在 iphone5 还是 iPhone 4 上运行我的应用程序,它都应该调整视图。它不应该被扭曲。所以请建议我如何指定约束以便它将注意身高。
  • 似乎您并不清楚您希望您的应用看起来像什么...您不在乎顶部视图是否为 1 pt 高而中间视图为 499 pts ?

标签: iphone objective-c autolayout


【解决方案1】:

您似乎并不关心顶视图和中间视图的高度是多少,所以我只是要为您做出决定:它们将具有相同的高度。为这三个视图(_topView、_middleView 和 _bottomView)作为子视图的公共父视图添加以下约束:

NSString *vfl = @"V:|-(10)-[topView]-(10)-[middleView]-(10)-[bottomView(==30)]-(10)-|";
NSDictionary *dict = @{@"topView":_topView,@"middleView":_middleView,@"bottomView":_bottomView};
NSArray *a = [NSLayoutConstraints 
                     constraintsWithVisualFormat: vfl
                                         options: 0
                                         metrics: nil
                                           views: dict];

确保它们也水平对齐:

NSArray *b = [NSLayoutConstraints 
           constraintsWithVisualFormat: @"H:|-(10)-[topView]-(10)-|"
                               options: 0
                               metrics: nil
                                 views: dict];
NSArray *c = [NSLayoutConstraints 
            constraintsWithVisualFormat: @"H:|-(10)-[middleView]-(10)-|"
                                options: 0
                                metrics: nil
                                  views: dict];
NSArray *d = [NSLayoutConstraints 
            constraintsWithVisualFormat: @"H:|-(10)-[bottomView]-(10)-|"
                                options: 0
                                metrics: nil
                                  views: dict];

编辑

如您所说,中间视图将是一个标签。标签具有固有的内容大小。如果你不设置这个视图的高度,自动布局系统会本能地知道该做什么。 (整洁,对吗?)通过将 _topView 的顶部固定到超级视图的顶部,并将其底部固定到标签的顶部,它的高度应该会自动计算。我已更改代码以反映这一点。

编辑 2

为了在代码中添加约束,找到这三个视图的共同祖先(超级视图)并写[superview addConstraints:a],[superview addConstraints:b], etc...确保IB中的自动布局已关闭,并将translateResizingMasksToConstraints设置为NO

【讨论】:

  • 请参考我上面的评论。
  • 感谢您的快速回复,但我正在使用 IB,请您告诉我使用 IB 的情况。
  • 其实,不,我不能。不是因为我不想,而是因为我永远无法让 IB 以我想要的方式工作。尽管 Apple 说 IB 是最好的方法,但我发现自动布局代码更易于使用和调试。我认为 XCode 5 中的 IB 让事情变得更容易一些,但我们还不能谈论它。我建议您尝试使用代码,就像实验一样。也许你会喜欢它! :-)
  • 好的,我会试试的,但是我从来没有使用过自动布局的代码,所以首先我需要了解它。如果你建议一些相同的链接真的很好。因为我没有找到我的使用代码自动布局的好教程。
  • 我已经稍微改变了我的答案,以帮助你一路走来。最好的建议是 Erica Sadun 的书“Autolayout Demystified”。她完全改变了我对自动布局的看法。否则,这是一个很好的简要概述:technology.amis.nl/2013/06/07/autolayout。 Apple 文档不是很有帮助,但也许您仍然会学到一些东西:developer.apple.com/library/mac/#documentation/UserExperience/…