UIView 以编程方式设置约束

UIView Setting Constraints Programmatically

我是 iOS 的新手,还不太了解约束。我正在向我的视图控制器添加一组动态视图,默认情况下它在顶部包含一个滚动视图和一个容器视图。一切正常,我设法使用以下方法将它们添加到彼此之下:

TheView.frame = CGRectMake(5, CGFloat(position), self.view.frame.size.width-10, 40); //position is incremented so that they are below each other

但是当我将 phone 转为横向时,视图不占用主视图的宽度,所以我在视图中添加了以下内容:

TheView.translatesAutoresizingMaskIntoConstraints = false;
    let margins = contentView.layoutMarginsGuide // contentView is the container view
    TheView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor).active = true
    TheView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor).active = true

当我旋转设备时,这使得视图动态改变了它们的宽度,但它们现在重叠了,我似乎无法找到如何将它们设置为像它们原来那样放置在彼此下方。

更新:

我从情节提要中删除了滚动视图和所有内容,并以编程方式添加了滚动视图和堆栈视图。

在视图中加载:

ScrollView = UIScrollView()
        ScrollView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(ScrollView)

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllCenterX, metrics: nil, views: ["scrollView": ScrollView]))
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllCenterX, metrics: nil, views: ["scrollView": ScrollView]))


        stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.distribution  = UIStackViewDistribution.EqualSpacing
        stackView.spacing   = 26.0
        stackView.axis = .Vertical
        ScrollView.addSubview(stackView)


        ScrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[stackView]|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))
        ScrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[stackView]|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))

添加动态视图:

for loop...

let Description = UILabel()
stackView.addArrangedSubview(Description)

let Value = UITextField()
stackView.addArrangedSubview(Value)

视图和以前一样添加成功,并且有滚动。视图也填充了堆栈视图(宽度)但仍然不是横向的。

你不能同时:

  • 为您的观点定义一个frame
  • 为这些视图定义一组约束

你做一个或另一个。

你好像用了iOS9个APIconstraintEqualToAnchor,所以你也可以把你要堆叠的2个视图放到一个UIStackView里,这样肯定是最简单的解决方案。

如果您需要支持旧版本的 iOS (7, 8),这仅意味着您没有定义足够的约束来放置您的视图。 TheView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor) => 这个放在 TheView 左侧(嗯,'leading',因为它可能取决于显示语言的方向 - 例如,它适合阿拉伯语) TheView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor)约束对方

你有 2 个水平约束,所以你错过了另外 2 个垂直轴约束。

其中一个约束可能是 topAnchorbottomAnchor(取决于 TheView 的位置 - 顺便说一下,实例变量的大写字母非常不常见 :)

另一个约束可能定义在 TheView 和另一个子视图之间,例如

let viewTop = NSLayoutConstraint(item: TheView, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Bottom, multiplier: 1, constant: 0) ,如果你想把 TheView 放在 scrollView

下面

请注意 UIScrollView 与自动布局的行为略有不同。 您必须为其层次结构之外的视图提供一组约束(以约束 scrollview bounds),并且您可以使用另一组约束来放置 scrollView 的子视图(这样,约束其 contentSize )(参见 Apple Technical Note on how to layout UIScrollView with constraints