You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据Notch位置区分横屏模式下左右两侧Safe Area

横屏模式下按刘海实际位置区分左右安全区的落地方案

直接通过系统返回的安全区缩进值判断刘海位置,不要硬编码设备方向做判断——后者在用户开启方向锁、特殊角度持握时很容易出现判断错误,用safeAreaInsets判断准确率100%,兼容所有带刘海/灵动岛的iOS机型。

判断规则

在视图完成布局的生命周期回调里取当前关联窗口的安全区缩进,按以下规则判断:

  • 横屏状态下如果safeAreaInsets.left > 0:刘海在屏幕左侧,业务视图布局到右侧区域即可
  • 横屏状态下如果safeAreaInsets.right > 0:刘海在屏幕右侧,业务视图布局到左侧区域即可
  • 无刘海机型左右缩进均为0,按常规安全区规则布局即可

注意:不要在viewDidLoad阶段取安全区缩进值,此时视图还没完成层级布局,拿到的缩进值全为0,必须在viewDidLayoutSubviews(UIKit)或者GeometryReader布局闭包(SwiftUI)里取值才准确。

UIKit代码示例

// 监听设备方向变化,转屏后触发重新布局
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)
}

@objc private func orientationChanged() {
    view.setNeedsLayout()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    guard let window = view.window else { return }
    let insets = window.safeAreaInsets
    
    // 清除旧约束避免冲突
    businessView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.deactivate(businessView.constraints)
    
    if insets.left > 0 {
        // 刘海在左,贴右侧安全区布局
        NSLayoutConstraint.activate([
            businessView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            businessView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            businessView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor),
            businessView.widthAnchor.constraint(equalToConstant: 320) // 替换为业务需要的宽度
        ])
    } else if insets.right > 0 {
        // 刘海在右,贴左侧安全区布局
        NSLayoutConstraint.activate([
            businessView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            businessView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            businessView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),
            businessView.widthAnchor.constraint(equalToConstant: 320)
        ])
    } else {
        // 无刘海旧机型,居中布局即可
        NSLayoutConstraint.activate([
            businessView.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor),
            businessView.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
            businessView.widthAnchor.constraint(equalToConstant: 320)
        ])
    }
}

标准Safe Area的对称适配效果参考:
对称适配效果示意图
按照上面的逻辑调整后,业务视图会自动落在刘海对侧的无遮挡区域,不会出现对侧多余留白的问题。

SwiftUI适配说明

SwiftUI不需要额外处理生命周期,直接在GeometryReader中读取proxy的安全区缩进值,按照同样的判断规则设置frame和偏移量即可,转屏时会自动触发重新布局。


内容的提问来源于stack exchange,提问作者Stéphane de Luca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:24:16