[英]Keep autolayout constraints active status on device rotation
已安裝是指安裝大小類,而不是活動 / 非活動 。
您必須以編程方式創建另一個約束,並激活/停用該約束。 這是因為您無法更改約束的乘數( 我可以更改NSLayoutConstraint的乘數屬性嗎? ),也不能修改大小類( activateConstraints:和deactivateConstraints:在IB中創建的約束后不會保持旋轉 )。
有幾種方法可以做到這一點。 在下面的示例中,我使用乘數或1/2創建x1約束的副本。 然后我在兩者之間切換:
@IBOutlet var fullWidthConstraint: NSLayoutConstraint!
var halfWidthConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
halfWidthConstraint = NSLayoutConstraint(item: fullWidthConstraint.firstItem,
attribute: fullWidthConstraint.firstAttribute,
relatedBy: fullWidthConstraint.relation,
toItem: fullWidthConstraint.secondItem,
attribute: fullWidthConstraint.secondAttribute,
multiplier: 0.5,
constant: fullWidthConstraint.constant)
halfWidthConstraint.priority = fullWidthConstraint.priority
}
@IBAction func changeConstraintAction(sender: UISwitch) {
if sender.on {
NSLayoutConstraint.deactivateConstraints([fullWidthConstraint])
NSLayoutConstraint.activateConstraints([halfWidthConstraint])
} else {
NSLayoutConstraint.deactivateConstraints([halfWidthConstraint])
NSLayoutConstraint.activateConstraints([fullWidthConstraint])
}
}
在iOS 9+ , Xcode 7+上測試過。
我將描述如何在兩個布局之間進行簡單切換。
當屏幕旋轉時,Autolayout將應用具有更高優先級的已安裝默認布局。 Constraint是否處於活動狀態並不重要。 因為,在旋轉時,會重新安裝故事板上的高優先級布局並且active = true。 因此,即使您更改了活動狀態,也會在旋轉時應用默認布局,並且無法保留任何布局。
切換兩個布局,而不是切換活動狀態。 在兩個布局之間切換時,請使用“優先級”而不是“活動”。 這種方式不需要擔心活動狀態。 這很簡單。
首先,在Storyboard上創建兩個要切換的布局。 檢查兩者是否已安裝。 發生沖突錯誤,因為兩個布局的優先級= 1000(必需)。 將要首先顯示的布局的優先級設置為“高”。 並將其他布局的優先級設置為低,將解決沖突錯誤。 將這些布局的約束關聯為類的IBOutlet。 最后,只需在要更改布局的時間切換高和低之間的優先級。 請注意,請不要將優先級更改為“required”。 優先級設置為必需的布局在此之后無法更改。
class RootViewController: UIViewController {
@IBOutlet var widthEqualToSuperView: NSLayoutConstraint!
@IBOutlet var halfWidthOfSuperview: NSLayoutConstraint!
override func viewDidLayoutSubviews() {
changeWidth()
}
func changeWidth() {
let orientation = UIApplication.shared.statusBarOrientation
if (orientation == .portrait || orientation == .portraitUpsideDown) {
widthEqualToSuperView.priority = UILayoutPriorityDefaultHigh;
halfWidthOfSuperview.priority = UILayoutPriorityDefaultLow;
}
else {
widthEqualToSuperView.priority = UILayoutPriorityDefaultLow;
halfWidthOfSuperview.priority = UILayoutPriorityDefaultHigh;
}
}
}
您可以使用IB為大小類創建的約束進行必要的切換。 訣竅是將折疊狀態保持在變量中並更新約束事件中的約束以及特征集合更改事件。
var collapsed: Bool {
didSet {
view.setNeedsUpdateConstraints()
}
}
@IBAction func onButtonClick(sender: UISwitch) {
view.layoutIfNeeded()
collapsed = !collapsed
UIView.animate(withDuration: 0.3) {
view.layoutIfNeeded()
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
view.setNeedsUpdateConstraints()
}
override func updateViewConstraints() {
constraint1.isActive = !collapsed
constraint2.isActive = collapsed
super.updateViewConstraints()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.