水平约束在 UIScrollView 中无法正常工作。 (程序约束)

Horizontal constraint not working correctly in a UIScrollView. (programatic constraints)

快速解释。

我有一个 UIScrollView,那是 "self.view" 的子视图。 我的 UIScrollview,有一个名为 contentView

的子视图

我所有的其他对象都是 contentView 的子视图或者它是 sub-views

除了 2 个视图外,所有内容看起来都正确。

在我的约束中添加这些视图后。整个contentView向左移动,打破一切。

这是一个屏幕图像,其中包含名为 (howManyIconView) 的麻烦视图,它是蓝色的 UIView,中间有一个白色的松弛图标。 (左下角)

为了让大家明白是 contentView 搞砸了,我给 contentView 设置了红色背景。

这是相同的视图,但没有将 howManyIconView 添加到我的约束中。

到与问题相关的实际代码,从头开始。

contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
scrollView.addSubview(contentView)

howManyContentView.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.addSubview(howManyContentView)

howManyIconView.setTranslatesAutoresizingMaskIntoConstraints(false)
howManyIconView.backgroundColor = UIColor.formulaBlueColor()
howManyContentView.addSubview(howManyIconView)

howManyIcon.setTranslatesAutoresizingMaskIntoConstraints(false)
howManyIcon.textColor = UIColor.formulaWhiteColor()
howManyIcon.font = UIFont(name: "fontAwesome", size: 20)
howManyIcon.text = ""
howManyIconView.addSubview(howManyIcon)

限制条件如下:

    var viewsDictionary = ["contentView":contentView,"howManyContentView":howManyContentView,
            "howManyLabel":howManyLabel,
            "howManyInputField":howManyInputField,
            "howManyIconView":howManyIconView,
            "howManyIcon":howManyIcon]

    let metricsDictionary = ["topBarHeight":6,"numbersViewRowHeight":49,"numbersViewSeperatorHeight":1,"inputFieldHeight":75,"contentWidth":self.view.bounds.width,"grapViewHeight":175,"inputFieldWidth":100,"iconViewWidth":50]

            scrollView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:[contentView(contentWidth)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary))

        howManyContentView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "V:[howManyIconView(inputFieldHeight)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary))
        howManyContentView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "V:[howManyInputField(inputFieldHeight)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary))

contentView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:|[howManyContentView]|", options: nil, metrics: nil, views: viewsDictionary))

        howManyContentView.addConstraint(NSLayoutConstraint(item:howManyLabel, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyContentView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0))
        howManyContentView.addConstraint(NSLayoutConstraint(item:howManyInputField, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyContentView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0))
        howManyContentView.addConstraint(NSLayoutConstraint(item:howManyIconView, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyContentView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0))
        howManyIconView.addConstraint(NSLayoutConstraint(item:howManyIcon, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyIconView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0))
        howManyIconView.addConstraint(NSLayoutConstraint(item:howManyIcon, attribute:NSLayoutAttribute.CenterX, relatedBy:NSLayoutRelation.Equal, toItem:howManyIconView, attribute:NSLayoutAttribute.CenterX, multiplier:1.0, constant:0))


        howManyContentView.addConstraints(
    NSLayoutConstraint.constraintsWithVisualFormat(
        "H:|-32-[howManyLabel]", options: nil, metrics: metricsDictionary, views: viewsDictionary))

下面的约束,是一个把一切都搞砸的约束。一旦我从那 1 行代码中删除 [howManyIconView(iconViewWidth)],一切都很好。

howManyContentView.addConstraints(
    NSLayoutConstraint.constraintsWithVisualFormat(
        "H:[howManyIconView(iconViewWidth)][howManyInputField(inputFieldWidth)]-32-|", options: nil, metrics: metricsDictionary, views: viewsDictionary))

我已经三次检查过 howManyContentView、howManyIconView 和 howManyIcon 未在本 post 中未显示的任何代码中提及。

这是我尝试解决问题的方法

首先,我尝试制作另一个名为 HowManyInputView 的视图,我将 iconViewUITextField 放入其中。然后将其作为唯一的约束。 (相同的结果)

之后,我尝试删除所有与 iconView 中的 UILabel 有关的内容。看看它是否与标签有关。 (相同的结果)

然后我试着做了一个新的视图。并给它类似(但不相同)的位置约束(同样的问题),这个视图也没有任何子视图,进一步表明它是视图而不是 UILabel 导致我的问题。

所以我尝试将我的水平约束拆分为 2。如您在代码中看到的那样。我在同一行代码中给了它一个宽度和一个水平约束。所以我为它制作了 2 条不同的约束线,一条用于水平调整大小,一条用于定位。 (相同的结果)

此时我运行没主意了。所以我删除了我的派生数据文件夹,并清理了我的项目。 (仍然无法正常工作)

接下来我尝试打印出有问题的视图的约束。像这样使用 constraintsAffectingLayoutForAxis

println("Horizontal: \(howManyIconView.constraintsAffectingLayoutForAxis(UILayoutConstraintAxis.Horizontal))")

println("Vertical: \(howManyIconView.constraintsAffectingLayoutForAxis(UILayoutConstraintAxis.Vertical))")

这是控制台打印的内容:

Horizontal: [<NSLayoutConstraint:0x174299050 H:[UIView:0x17019df60(50)]>]

Vertical: [<NSLayoutConstraint:0x17429aae0 V:|-(0)-[UIView:0x17019df60]   (Names: '|':UIView:0x17019ddc0 )>, <NSLayoutConstraint:0x17429ab30 V:[UIView:0x17019df60]-(0)-|   (Names: '|':UIView:0x17019ddc0 )>]

除非我读错了。看起来 iconView 只是获得了 (50) 的大小约束,而不是实际的位置水平约束。尽管正确地放在了我的 UITextField?

旁边

为什么会出现这种情况仍然是个谜,据我所知,我的水平定位约束应该没问题。没有收到任何错误。但希望提供我的问题的原因,将有助于解决问题。

如有任何帮助,我们将不胜感激! (None 我的尝试导致控制台出现错误。)

我看到了 2 个可能的错误:

  1. 我没有看到 contentView 左右的约束。我相信它们都应该为零。否则 contentView 在 scrollView 中的位置将是随机的。这应该通过将 H:[contentView(contentWidth)] 替换为 H:|[contentView(contentWidth)]|

  2. 来解决
  3. contentView 宽度使用 self.view.bounds.width 可能有点冒险 - 取决于您调用它的方法。确定和屏幕尺寸一样吗?

请注意,通常在 Interface Builder 中设置约束更容易,因为它总是会警告您缺少约束。