iPad应用横屏内容超出屏幕时如何开启滚动,竖屏适配时禁用滚动?
实现方案
步骤1:调整基础布局结构
- 把当前页面所有已加好约束的内容,整体移入一个自定义的
UIView(下文称contentView)中,保证contentView内部原有约束完全保留。 - 新增一个
UIScrollView作为页面根视图的直接子视图,给ScrollView加四个边距约束,上下左右全等于父视图的对应边距,铺满整个屏幕。 - 将contentView作为ScrollView的唯一子视图,给contentView加约束:上下左右等于ScrollView的content layout guide对应边距,宽度等于ScrollView的frame layout guide宽度。
步骤2:配置动态高度约束
给contentView添加两个高度约束:
- 约束1:
contentView高度 ≥ 父视图(页面根视图)高度,优先级设为1000(必填) - 约束2:
contentView高度 = 父视图高度,优先级设为250(可选)
这两个约束的作用是:竖屏时内容刚好适配屏幕高度,约束2生效,contentView高度和屏幕一致;横屏时屏幕高度变小,约束1自动生效,contentView高度保持原有适配竖屏的高度,超出屏幕的部分由ScrollView承载。
步骤3:监听屏幕方向控制滚动开关
只需要在方向切换时控制ScrollView的滚动开关即可,不需要手动计算任何尺寸:
override func viewDidLoad() { super.viewDidLoad() // 注册屏幕方向变化监听 NotificationCenter.default.addObserver( self, selector: #selector(handleOrientationChange), name: UIDevice.orientationDidChangeNotification, object: nil ) // 初始状态设置 scrollView.isScrollEnabled = UIDevice.current.orientation.isLandscape } @objc private func handleOrientationChange() { let isLandscape = UIDevice.current.orientation.isLandscape scrollView.isScrollEnabled = isLandscape } // iOS 16+ 也可以用系统提供的方向切换回调,不需要监听通知 override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) let isLandscape = size.width > size.height scrollView.isScrollEnabled = isLandscape }
注意事项
- 要保证contentView内部的约束链条完整:最顶部的子控件顶部约束贴contentView顶部,最底部的子控件底部约束贴contentView底部,系统会自动计算ScrollView的contentSize,无需手动赋值。
- 如果使用Storyboard/XIB开发,上述所有约束和优先级配置都可以直接在界面构建器中完成,无需手写代码。
内容的提问来源于stack exchange,提问作者Gonkikong
相关产品推荐
相关产品推荐

