Swift 4: UI 设备旋转后更新失败
Swift 4: UI fails to update after device rotation
我想将 bearImageView
的宽度和高度从纵向 -> 横向更改为 100,而从相反方向更改为 200。
在 setupLayout
中,我调用停用然后激活 widthAnchor
和 heightAnchor
上的约束。所以我期待它改变宽度和高度。
问题:调到100,但没有变回200。
为什么会这样?
这是代码。
class ViewController: UIViewController {
// closure objects
let bearImageView: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "bear_first")) // type `image literal` and double click
imageView.translatesAutoresizingMaskIntoConstraints = false // enable autolayout
return imageView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(bearImageView) // display image
setupLayout(imageView: bearImageView) // apply constraints
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("landscape")
setupLayout(imageView: bearImageView) // apply constraints
} else {
print("portrait")
setupLayout(imageView: bearImageView) // apply constraints
}
}
private func setupLayout(imageView: UIImageView){
if UIDevice.current.orientation.isLandscape == true {
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = false
imageView.heightAnchor.constraint(equalToConstant: 200).isActive = false
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 100).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 100).isActive = true
print("changed to landscape")
} else {
imageView.widthAnchor.constraint(equalToConstant: 100).isActive = false
imageView.heightAnchor.constraint(equalToConstant: 100).isActive = false
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 200).isActive = true
print("changed to portrait")
}
}
这是错误。
[LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x6000031923a0 UIImageView:0x7fbf72508060.width == 200 (active)>",
"<NSLayoutConstraint:0x6000031e4730 UIImageView:0x7fbf72508060.width == 100 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000031923a0 UIImageView:0x7fbf72508060.width == 200 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
请注意,constraint
方法会为您的图像视图创建 新。
当您在 viewDidLoad
中首次调用 setupLayout
时,图像视图中添加了 200 的宽度和高度限制。然后旋转设备以更改为横向。 setupLayout
再次被调用。这次它添加了 100 的宽度和高度约束,,但它不会停用您之前添加的常数 200 的约束。执行此行:
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = false
创建新的非活动约束,not 停用旧约束。
你应该做的是将宽度和高度约束存储为 ViewController
:
的属性
var widthConstraint: NSLayoutConstraint!
var heightConstraint: NSLayoutConstraint!
并且在 setupLayout
中,分配给那些属性:
private func setupLayout(imageView: UIImageView){
widthConstraint = imageView.widthAnchor.constraint(equalToConstant: 200)
heightConstraint = imageView.heightAnchor.constraint(equalToConstant: 200)
widthConstraint.isActive = true
heightConstraint.isActive = true
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
}
而且你应该只调用 setupLayout
一次。
然后创建另一个名为 updateConstraints
的方法来更新 widthConstraint
和 heightConstraint
的常量:
private func updateConstraints() {
if UIDevice.current.orientation.isLandscape {
heightConstraint.constant = 100
widthConstraint.constant = 100
} else {
heightConstraint.constant = 200
widthConstraint.constant = 200
}
}
在 viewWillTransitionToSize
而不是 setupLayout
中调用它。
我想将 bearImageView
的宽度和高度从纵向 -> 横向更改为 100,而从相反方向更改为 200。
在 setupLayout
中,我调用停用然后激活 widthAnchor
和 heightAnchor
上的约束。所以我期待它改变宽度和高度。
问题:调到100,但没有变回200。 为什么会这样?
这是代码。
class ViewController: UIViewController {
// closure objects
let bearImageView: UIImageView = {
let imageView = UIImageView(image: #imageLiteral(resourceName: "bear_first")) // type `image literal` and double click
imageView.translatesAutoresizingMaskIntoConstraints = false // enable autolayout
return imageView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(bearImageView) // display image
setupLayout(imageView: bearImageView) // apply constraints
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("landscape")
setupLayout(imageView: bearImageView) // apply constraints
} else {
print("portrait")
setupLayout(imageView: bearImageView) // apply constraints
}
}
private func setupLayout(imageView: UIImageView){
if UIDevice.current.orientation.isLandscape == true {
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = false
imageView.heightAnchor.constraint(equalToConstant: 200).isActive = false
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 100).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 100).isActive = true
print("changed to landscape")
} else {
imageView.widthAnchor.constraint(equalToConstant: 100).isActive = false
imageView.heightAnchor.constraint(equalToConstant: 100).isActive = false
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 200).isActive = true
print("changed to portrait")
}
}
这是错误。
[LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x6000031923a0 UIImageView:0x7fbf72508060.width == 200 (active)>",
"<NSLayoutConstraint:0x6000031e4730 UIImageView:0x7fbf72508060.width == 100 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000031923a0 UIImageView:0x7fbf72508060.width == 200 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
请注意,constraint
方法会为您的图像视图创建 新。
当您在 viewDidLoad
中首次调用 setupLayout
时,图像视图中添加了 200 的宽度和高度限制。然后旋转设备以更改为横向。 setupLayout
再次被调用。这次它添加了 100 的宽度和高度约束,,但它不会停用您之前添加的常数 200 的约束。执行此行:
imageView.widthAnchor.constraint(equalToConstant: 200).isActive = false
创建新的非活动约束,not 停用旧约束。
你应该做的是将宽度和高度约束存储为 ViewController
:
var widthConstraint: NSLayoutConstraint!
var heightConstraint: NSLayoutConstraint!
并且在 setupLayout
中,分配给那些属性:
private func setupLayout(imageView: UIImageView){
widthConstraint = imageView.widthAnchor.constraint(equalToConstant: 200)
heightConstraint = imageView.heightAnchor.constraint(equalToConstant: 200)
widthConstraint.isActive = true
heightConstraint.isActive = true
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
}
而且你应该只调用 setupLayout
一次。
然后创建另一个名为 updateConstraints
的方法来更新 widthConstraint
和 heightConstraint
的常量:
private func updateConstraints() {
if UIDevice.current.orientation.isLandscape {
heightConstraint.constant = 100
widthConstraint.constant = 100
} else {
heightConstraint.constant = 200
widthConstraint.constant = 200
}
}
在 viewWillTransitionToSize
而不是 setupLayout
中调用它。