【发布时间】:2020-08-11 16:32:59
【问题描述】:
我有 2 个 UIView,cv1 和 cv2。在纵向时,我希望 cv1 占据屏幕的上半部分,而 cv2 占据下半部分。当旋转成横向时,我希望 cv1 占据左半部分,而 cv2 占据右半部分,如下所示:
我是这样设置的(ChildView1 和 ChildView2 类只提供颜色和圆角):
class ViewController: UIViewController {
let cv1 = ChildView1()
let cv2 = ChildView2()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var safeAreaHeight: CGFloat {
if #available(iOS 11.0, *) {
return view.safeAreaLayoutGuide.layoutFrame.size.height
}
return view.bounds.height
}
//debugPrint("height = \(safeAreaHeight)")
var safeAreaWidth: CGFloat {
if #available(iOS 11.0, *) {
return view.safeAreaLayoutGuide.layoutFrame.size.width
}
return view.bounds.width
}
//debugPrint("width = \(safeAreaWidth)")
cv1.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
cv1.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
if UIDevice.current.orientation == .portrait || UIDevice.current.orientation == .portraitUpsideDown {
cv1.heightAnchor.constraint(equalToConstant: safeAreaHeight / 2).isActive = true
cv1.widthAnchor.constraint(equalToConstant: safeAreaWidth).isActive = true
cv2.topAnchor.constraint(equalTo: cv1.bottomAnchor, constant: 0).isActive = true
cv2.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
//debugPrint("Portrait: height = \(safeAreaHeight), width = \(safeAreaWidth)")
} else if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
cv1.heightAnchor.constraint(equalToConstant: safeAreaHeight).isActive = true
cv1.widthAnchor.constraint(equalToConstant: safeAreaWidth / 2).isActive = true
cv2.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
cv2.leftAnchor.constraint(equalTo: cv1.rightAnchor, constant: 0).isActive = true
//debugPrint("Landscape: height = \(safeAreaHeight), width = \(safeAreaWidth)")
}
cv2.heightAnchor.constraint(equalTo: cv1.heightAnchor).isActive = true
cv2.widthAnchor.constraint(equalTo: cv1.widthAnchor).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
addCV1()
addCV2()
}
func addCV1() {
self.view.addSubview(cv1)
cv1.translatesAutoresizingMaskIntoConstraints = false
}
func addCV2() {
self.view.addSubview(cv2)
cv2.translatesAutoresizingMaskIntoConstraints = false
}
}
如果我从纵向或横向开始,它看起来都很好。但是当我旋转屏幕时,两个视图都会消失,并且每个约束都会收到以下错误消息:
2020-08-11 10:28:55.328063-0600 RotateScreenTesting[91471:4449618] libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.
"Portrait: height = 603.0, width = 375.0"
2020-08-11 10:29:15.046153-0600 RotateScreenTesting[91471:4449618] [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:0x600003d74500 RotateScreenTesting.ChildView1:0x7fceba30a720.height == 301.5 (active)>",
"<NSLayoutConstraint:0x600003d6d180 RotateScreenTesting.ChildView1:0x7fceba30a720.height == 343 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003d6d180 RotateScreenTesting.ChildView1:0x7fceba30a720.height == 343 (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.
(lldb)
我做错了什么???
【问题讨论】:
-
在更新约束之前,你必须先清除旧的。
-
你做错了很多事情,但首先......你认为“纵向方向”是什么?如果应用在 iPad 上并且用户使用 SplitView / SlideOver 进行多任务处理,则设备可能处于“横向”方向,但您的应用可能又高又窄。
-
@DonMag:到目前为止,我只为 iPhone 做这件事,为 iPad 整理想法以备后用……我做错了什么? (我对此很陌生......)
-
@Niraj Solanki:我最初尝试通过设置 cv1.translatesAutoresizingMaskIntoConstraints = true 来做到这一点,然后再次设置为 false - 但这不起作用。您可能有以下解决方案...