UISplitViewController的PrimaryViewController视图frame值异常如何解决
UISplitViewController Primary视图frame异常问题解决方案
你遇到的问题由两个常见的布局错误导致:
- 给当前view的子视图设置frame时误用了当前view的
frame属性,应该使用bounds属性。frame描述的是视图在其父视图坐标系中的位置和大小,bounds描述的是视图自身内部坐标系的位置和大小,添加到当前view上的子视图的坐标需要基于当前view的bounds计算,否则如果当前view在父视图中的origin不为(0,0),子视图就会出现偏移,超出当前view的显示范围。 - 布局代码的触发时机选择不当,
viewDidAppear是视图已经展示在屏幕上之后才会调用,此时添加视图会有可见的延迟,而且如果视图后续发生大小变化(如横竖屏切换、iPad分屏调整),写死的frame不会自动更新。
方案1:修改现有frame写法快速修复
将布局逻辑移到布局完成的回调方法viewDidLayoutSubviews中,同时使用bounds计算子视图位置,避免重复添加子视图:
// 声明属性持有测试视图,避免重复添加 private var testView: UIView? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .yellow // 仅在视图加载时创建一次子视图 let testView = UIView() testView.backgroundColor = .black.withAlphaComponent(0.3) view.addSubview(testView) self.testView = testView } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // 每次布局更新时重新计算子视图frame,使用bounds testView?.frame = view.bounds.insetBy(dx: 30, dy: 30) // 此处打印的bounds即为当前视图的正确内部尺寸 print("view bounds:\(view.bounds)") }
方案2:使用自动布局(更推荐)
不需要手动管理frame,系统会自动适配所有布局变化,包括横竖屏切换、分屏大小调整等场景:
override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .yellow let testView = UIView() testView.backgroundColor = .black.withAlphaComponent(0.3) // 禁用自动转换 autoresizing 掩码为约束 testView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(testView) // 激活四边边距约束 NSLayoutConstraint.activate([ testView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30), testView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30), testView.topAnchor.constraint(equalTo: view.topAnchor, constant: 30), testView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -30) ]) }
内容的提问来源于stack exchange,提问作者reza23
相关产品推荐
相关产品推荐

