简体   繁体   English

以编程方式更改约束仅影响视图的可见部分

[英]Changing constraints programmatically only affects visible parts of the view

I built a TableView with static cells in Interface Builder with two sets of constraints. 我在Interface Builder中使用两组静态约束构建了带有静态单元格的TableView。 One for an editing view and one just for viewing. 一种用于编辑视图,另一种仅用于查看。 It is not much just changing the position of three textboxes. 只是改变三个文本框的位置并不多。

The first set of constraints is activated in the interface builder and the second one is deactivated ("Installed" is not checked). 第一组约束在接口构建器中被激活,第二组约束被停用(未选中“已安装”)。

Then when the user clicks on "Edit" at first the old constraints are deactivated and the other ones are activated: 然后,当用户首先单击“编辑”时,旧的约束将被停用,而其他约束将被激活:

@IBOutlet var nonEditableConstraints: [NSLayoutConstraint]!
@IBOutlet var editableConstraints: [NSLayoutConstraint]!

override func setEditing(editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)

        view.layoutIfNeeded()

        if (animated) {
            UIView.animateWithDuration(1.0) { () -> Void in
                self.setControlsEditing(editing)
                self.setContraintsEditing(editing)
                self.view.layoutIfNeeded()
            }
        } else {
            setControlsEditing(editing)
            setContraintsEditing(editing)
        }
    }

private func setContraintsEditing(editing: Bool) {
        // we need to make sure to deakcivate constraints before activating new ones
        if (editing) {
            for constraint in nonEditableConstraints {
                constraint.active = false
            }

            for constraint in editableConstraints {
                constraint.active = true
            }
        } else {
            for constraint in editableConstraints {
                constraint.active = false
            }

            for constraint in nonEditableConstraints {
                constraint.active = true
            }
        }
    }

This works well. 这很好。 The only thing is that whenever a part of the three "macro nutrition" fields which are subject to constraint changes are not visible when the constraints are changed they stay in their default state (the state set by IB). 唯一的事情是,只要更改约束条件后,只要三个“宏营养”字段中受约束条件更改的一部分不可见,它们就会保持默认状态(IB设置的状态)。 This occurs when the iPhone is in landscape mode. 当iPhone处于横向模式时,会发生这种情况。 A few examples: 一些例子:

This is how it looks in default mode (set by IB): 这是默认模式(由IB设置)下的外观: 在此处输入图片说明

When I press Edit while all three textboxes are visible (correctly layoutet): 当我在三个文本框都可见的情况下按“编辑”(正确的布局): 在此处输入图片说明

This is how it looks in landscape when I pressed edit before scrolling down (carbohydrates were not visible). 这是我在向下滚动之前按编辑键时所看到的风景(碳水化合物不可见)。 When I press Done and that Edit again everything is correct since all textboxes are visible: 当我按“完成”并再次单击“编辑”时,由于所有文本框均可见,因此一切正确: 在此处输入图片说明

I solved it myself. 我自己解决了。 Apparently you should only change constraints in the viewDidLayoutSubviews() method of the view controller. 显然,您只应在视图控制器的viewDidLayoutSubviews()方法中更改约束。 I changed the code in this way which is working: 我以这种方式更改了代码,使其正常工作:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    setContraintsEditing(editing)
}

override func setEditing(editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)

    if (animated) {
        view.layoutIfNeeded()
        UIView.animateWithDuration(1.0) { () -> Void in
            self.setControlsEditing(editing)
            self.view.layoutIfNeeded()
        }
    } else {
        setControlsEditing(editing)
    }
}

As you see the setContraintsEditing(bool) method now is called from the right place which is called by the animation block indirectly by layoutIfNeeded(). 如您所见,现在从正确的位置调用setContraintsEditing(bool)方法,该方法由动画块由layoutIfNeeded()间接调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM