好的,我必须对您尝试实现的布局进行一些推断,因为您没有准确指定它。我假设您有一个带有按钮的 UIScrollView 作为使事情复杂化的子视图。
由于您是约束的新手,让我们从一个更简单的案例开始,它是一个 UIButton,它是一个 UIView 的子视图。 UIButton 已经知道它的宽度和高度应该基于它的内容,所以你只需要指定它的 x 和 y 位置(2 个约束)。我个人更喜欢书写约束的方程形式而不是视觉格式,所以我会使用它。你想要的是:
button.x = button.superview.x*1 + 0;
button.y = button.superview.x*1 + 0;
.x 是leading 约束(前导从左开始),.y 是top 约束(从顶部开始)。
接下来,由于约束是在子视图和它的父视图之间,你将约束添加到父视图
[button.superview addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:button.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:164.0]];
[button.superview addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:button.superview attribute:NSLayoutAttributeLeading multiplier:1.0 constant:165.0]];
这会将您的按钮定位在 (164,165),并且按钮的宽度和高度将来自按钮的固有大小(基于其图像/文本)。
所以这是一个简单的案例。现在让我们转向您的 button.superview 是 UIScrollView 的场景。这更复杂,因为您需要以不同的思维方式考虑 UIScrollview 的约束,即就像它是将固定的窗口大小(框架)变成无限大小的景观(contentSize)。
假设您有一个 UIView --> UIScrollView --> UIButton,其中 UIView 有一个子滚动视图,而子滚动视图又具有一个 UIButton 作为子视图。一步一步来。
1.) UIView --> UIScrollView
您在这对上编写的约束位于 UIView 的框架和 UIScrollView 的 框架 之间。这很容易,因为框架是固定大小的。因此,假设您希望 UIScrollView 成为它嵌入的 UIView 的完整大小。您将编写 4 个约束来指定它的 X、Y、宽度和高度。当然有很多方法可以做到这一点,我会列出一种。
scrollview.x (scrollview.frame.x) = scrollview.superview.x*1 + 0;
scrollview.y (scrollview.frame.y) = scrollview.superview.y*1 + 0;
scrollview.width (scrollview.frame.width) = scrollview.superview.width*1 + 0;
scrollview.height (scrollview.frame.height) = scrollview.superview.height*1 + 0;
在约束条件下,这将是:
// Let's constrain the scrollview to stick to the top and left of it's superview
[scrollView.superview addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
[scrollView.superview addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView.superview attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
// Let's constrain the scrollview to make its width and height equal to its superview
[scrollView.superview addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView.superview attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];
[scrollView.superview addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:scrollView.superview attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]];
好的,现在滚动视图知道如何定位它的框架了。这是最简单的部分。
2.) 将按钮放置在滚动视图内。
好的,现在你必须改变你的想法。由于scrollView是按钮的父级,所以不能约束到scrollView的frame,而必须约束到scrollView的contentView。这在理论上是一个无限平面。
那么如何将视图限制在无限平面中? UIScrollView 中没有设置做这样的事情,所以我们卡住了吗?
不,我们需要为我们的 UIScrollView 定义一个内容视图。让我们将另一个视图拖到 UIScrollView 中,并将按钮放置在该视图中。我们的视图层次现在应该是这样的。
UIView (topView) --> UIScrollView --> UIView (contentView) --> UIButton(全部嵌套)。
现在我们需要设置约束来定义 contentView 的大小。假设 contentView 与 topView 大小相同。让我们添加约束来实现它。以下 4 个约束表示内容视图是滚动视图的平面。
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]];
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0]];
但这还不够,因为我们说过滚动视图基本上是一个进入无限平面的窗口。所以我们需要对我们的 contentView 增加 2 个约束来指定它的宽度和高度。让我们让它们与顶级视图相同。请注意,我们在 contentView 和 topView 之间设置了约束,完全绕过了 ScrollView。
// You could make the constant parameter non-zero if you wanted it to be bigger/smaller (+/-) than the view
[topView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:topView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];
[topView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:topView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]];
现在我们终于可以在按钮上定义约束了,可以写成下面这样你跟着,也可以写成最上面的定义,因为 contentView == button.superview。
[contentView addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:164.0]];
[contentView addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:contentView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:165.0]];
现在我们应该已经正确设置了所有约束。要强制布局,只需致电[topView layoutIfNeeded] 希望这很清楚,如果您有任何问题,请告诉我。我可能错过了一些东西,因为我不得不把它写下来:)