使用 constraintEqualToAnchor() 时如何在设置自动布局约束后更改它们?
How to change Auto Layout constraints after they are set when using constraintEqualToAnchor()?
我尝试使用 constraintEqualToAnchor()
:
来设置具有自动版式约束的视图
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orangeColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true
myView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100).active = true
}
在最后一行代码中,我尝试更改其中一个约束。我认为它会起作用,但它在控制台日志中给出了一些错误
"<NSLayoutConstraint:0x7fb53a5180d0 H:|-(0)-[UIView:0x7fb53a5190b0](LTR) (Names: '|':UIView:0x7fb53a519240 )>",
"<NSLayoutConstraint:0x7fb53a51f660 H:[UIView:0x7fb53a519240]-(-100)-[UIView:0x7fb53a5190b0](LTR)>",
"<NSLayoutConstraint:0x7fb53a711ee0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fb53a519240(414)]>"
使用 constraintEqualToAnchor()?
时,设置约束后更改约束的正确方法是什么?
这是声明约束的示例 c
,稍后将引用它。我们设置一个新的常量值,然后在父视图上调用 layout
。
myView.translatesAutoresizingMaskIntoConstraints = false
var constraints: [NSLayoutConstraint] = [
myView.topAnchor.constraintEqualToAnchor(view.topAnchor),
myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor),
myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
]
let c = myView.rightAnchor.constraintEqualToAnchor(view.rightAnchor)
constraints.append(c)
view.addSubview(myView)
NSLayoutConstraint.activateConstraints(constraints)
// Some time later
c.constant = -100
view.setNeedsLayout()
您需要在激活一个新约束时停用之前的约束,这样您就不会过度约束您的视图。为此,将对每个约束的引用存储为 ViewController
中的 属性,然后将旧约束的 active
属性 设置为 false
在创建和激活新约束之前:
Swift 2.x:
class ViewController: UIViewController {
var leftConstraint: NSLayoutConstraint?
var trailingConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orangeColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
leftConstraint?.active = true
trailingConstraint = myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor)
trailingConstraint?.active = true
topConstraint = myView.topAnchor.constraintEqualToAnchor(view.topAnchor)
topConstraint?.active = true
bottomConstraint = myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
bottomConstraint?.active = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
leftConstraint?.active = false
leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100)
leftConstraint?.active = true
}
}
更新 Swift 3 语法:
class ViewController: UIViewController {
var leftConstraint: NSLayoutConstraint?
var trailingConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orange
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
leftConstraint = myView.leftAnchor.constraint(equalTo: view.leftAnchor)
leftConstraint?.isActive = true
trailingConstraint = myView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
trailingConstraint?.isActive = true
topConstraint = myView.topAnchor.constraint(equalTo: view.topAnchor)
topConstraint?.isActive = true
bottomConstraint = myView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
bottomConstraint?.isActive = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
leftConstraint?.isActive = false
leftConstraint = myView.leftAnchor.constraint(equalTo: view.rightAnchor, constant: -100)
leftConstraint?.isActive = true
}
}
// method myView.topAnchor.constraintEqualToAnchor creates new one inactive anchor
// and not returns exist with equal relationships
// you can set identifier for any constraint in Interface Builder or code and find & update in code
for ( NSLayoutConstraint *c in [self.view constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal] )
{
if ( YES == [c.identifier isEqualToString:@"my.layout-constraint.id"] )
{
// Unlike the other properties, the constant can be modified
// after constraint creation.
// Setting the constant on an existing constraint performs much better
// than removing the constraint and adding a new one that's exactly like
// the old except that it has a different constant.
c.constant = 123;
// if needed
// [self.view setNeedsUpdateConstraints];
break;
}
}
下面是 if
语句修改 StackView
和 View
分段点击时的示例:
if (sender as AnyObject).selectedSegmentIndex == 0{
// Shrink the white view and stack view
heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 100)
heightConstraintView?.isActive = true
heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 100)
heightConstraintStackView?.isActive = true
} else {
// Before returning back the white view and stack view DEACTIVATE teh previous constraints
heightConstraintView?.isActive = false
heightConstraintStackView?.isActive = false
// Returning back the white view and stack view to normal size
heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 200)
heightConstraintView?.isActive = true
heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 200)
heightConstraintStackView?.isActive = true
}
我尝试使用 constraintEqualToAnchor()
:
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orangeColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true
myView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100).active = true
}
在最后一行代码中,我尝试更改其中一个约束。我认为它会起作用,但它在控制台日志中给出了一些错误
"<NSLayoutConstraint:0x7fb53a5180d0 H:|-(0)-[UIView:0x7fb53a5190b0](LTR) (Names: '|':UIView:0x7fb53a519240 )>",
"<NSLayoutConstraint:0x7fb53a51f660 H:[UIView:0x7fb53a519240]-(-100)-[UIView:0x7fb53a5190b0](LTR)>",
"<NSLayoutConstraint:0x7fb53a711ee0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fb53a519240(414)]>"
使用 constraintEqualToAnchor()?
时,设置约束后更改约束的正确方法是什么?
这是声明约束的示例 c
,稍后将引用它。我们设置一个新的常量值,然后在父视图上调用 layout
。
myView.translatesAutoresizingMaskIntoConstraints = false
var constraints: [NSLayoutConstraint] = [
myView.topAnchor.constraintEqualToAnchor(view.topAnchor),
myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor),
myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
]
let c = myView.rightAnchor.constraintEqualToAnchor(view.rightAnchor)
constraints.append(c)
view.addSubview(myView)
NSLayoutConstraint.activateConstraints(constraints)
// Some time later
c.constant = -100
view.setNeedsLayout()
您需要在激活一个新约束时停用之前的约束,这样您就不会过度约束您的视图。为此,将对每个约束的引用存储为 ViewController
中的 属性,然后将旧约束的 active
属性 设置为 false
在创建和激活新约束之前:
Swift 2.x:
class ViewController: UIViewController {
var leftConstraint: NSLayoutConstraint?
var trailingConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orangeColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
leftConstraint?.active = true
trailingConstraint = myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor)
trailingConstraint?.active = true
topConstraint = myView.topAnchor.constraintEqualToAnchor(view.topAnchor)
topConstraint?.active = true
bottomConstraint = myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
bottomConstraint?.active = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
leftConstraint?.active = false
leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100)
leftConstraint?.active = true
}
}
更新 Swift 3 语法:
class ViewController: UIViewController {
var leftConstraint: NSLayoutConstraint?
var trailingConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orange
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
leftConstraint = myView.leftAnchor.constraint(equalTo: view.leftAnchor)
leftConstraint?.isActive = true
trailingConstraint = myView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
trailingConstraint?.isActive = true
topConstraint = myView.topAnchor.constraint(equalTo: view.topAnchor)
topConstraint?.isActive = true
bottomConstraint = myView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
bottomConstraint?.isActive = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
leftConstraint?.isActive = false
leftConstraint = myView.leftAnchor.constraint(equalTo: view.rightAnchor, constant: -100)
leftConstraint?.isActive = true
}
}
// method myView.topAnchor.constraintEqualToAnchor creates new one inactive anchor
// and not returns exist with equal relationships
// you can set identifier for any constraint in Interface Builder or code and find & update in code
for ( NSLayoutConstraint *c in [self.view constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal] )
{
if ( YES == [c.identifier isEqualToString:@"my.layout-constraint.id"] )
{
// Unlike the other properties, the constant can be modified
// after constraint creation.
// Setting the constant on an existing constraint performs much better
// than removing the constraint and adding a new one that's exactly like
// the old except that it has a different constant.
c.constant = 123;
// if needed
// [self.view setNeedsUpdateConstraints];
break;
}
}
下面是 if
语句修改 StackView
和 View
分段点击时的示例:
if (sender as AnyObject).selectedSegmentIndex == 0{
// Shrink the white view and stack view
heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 100)
heightConstraintView?.isActive = true
heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 100)
heightConstraintStackView?.isActive = true
} else {
// Before returning back the white view and stack view DEACTIVATE teh previous constraints
heightConstraintView?.isActive = false
heightConstraintStackView?.isActive = false
// Returning back the white view and stack view to normal size
heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 200)
heightConstraintView?.isActive = true
heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 200)
heightConstraintStackView?.isActive = true
}