使用Xibs与代码开发、Storyboard仅做导航,横竖屏后View宽高未变如何解决?
解决横竖屏切换后获取View实时宽高的问题
嘿,我之前用纯Xib+代码开发、只把Storyboard当导航容器的时候,也碰到过这个横竖屏后宽高不更新的坑,给你几个实用的解决思路:
方法一:在viewWillLayoutSubviews中获取实时宽高
这是苹果官方推荐的处理布局变化的时机,每次View的布局发生改变(包括横竖屏切换、键盘弹出/收起)时,这个方法都会被调用,在这里获取的bounds是最准确的实时值:
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() // 获取当前View的实时宽高 let currentWidth = self.view.bounds.width let currentHeight = self.view.bounds.height print("当前View宽:\(currentWidth),高:\(currentHeight)") // 在这里根据新的宽高调整你的控件布局或者业务逻辑 }
方法二:监听屏幕边界变化通知
如果你需要在ViewController之外的地方也监听屏幕尺寸变化,可以用NotificationCenter监听UIScreen.boundsDidChangeNotification通知:
override func viewDidLoad() { super.viewDidLoad() // 注册屏幕边界变化的通知 NotificationCenter.default.addObserver( self, selector: #selector(screenBoundsChanged), name: UIScreen.boundsDidChangeNotification, object: nil ) } @objc private func screenBoundsChanged(_ notification: Notification) { guard let screen = notification.object as? UIScreen else { return } let screenBounds = screen.bounds // 这里的screenBounds就是横竖屏切换后的实时屏幕尺寸 print("屏幕实时宽:\(screenBounds.width),高:\(screenBounds.height)") // 如果需要同步更新View的布局,也可以在这里处理 updateViewLayout(with: screenBounds) } private func updateViewLayout(with bounds: CGRect) { // 根据新的屏幕尺寸调整View的布局 self.view.frame = bounds // 或者调整子控件的frame/constraints } // 记得在销毁时移除通知监听 deinit { NotificationCenter.default.removeObserver(self) }
额外注意事项
- 确保ViewController支持横竖屏:如果你的ViewController没开启横竖屏权限,切换方向也不会触发布局变化。可以重写这个属性来设置支持的方向:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { // 按需设置,比如支持所有方向或者特定方向 return .all }
- 避免在
viewDidLoad中缓存宽高:viewDidLoad只会调用一次,这里获取的宽高是初始状态的,横竖屏切换后不会更新,所以不要把宽高存在全局变量里一直用,要在布局变化的时机实时获取。
附上你提到的空ViewController界面:
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

