iOS界面布局:屏幕尺寸与安全区域全面指南

引言

随着iPhone和iPad的更新迭代,iOS设备的屏幕尺寸和设计也在不断变化。无论是iPhone X系列的刘海屏,还是最新的iPhone 14,开发者都需要面对适配不同设备布局的问题。在项目开发中,导航栏、状态栏、TabBar的高度以及安全区域的处理,直接影响到应用界面的美观与用户的交互体验。如果没有正确处理这些元素,应用在不同设备上的显示效果可能会失衡,甚至影响用户操作。

本文将详细介绍在iOS项目开发中获取这些屏幕的相关参数,帮助你打造在所有设备上都能正常运行的应用界面。

尺寸获取

在本篇博客中我们以Swift为例,在Swift中我们可以直接定义全局常量和全局的计算属性,在项目的任何地方进行引用。

屏幕宽高

屏幕的宽度和高度是开发中最常用的两个尺寸,几乎所有的UI适配都需要以屏幕的宽高为基础进行等分,或者减去左右,上下间距的方式来计算位置。我们可以直接通过主屏幕的bounds属性来获取屏幕的宽高:

Swift 复制代码
/// 屏幕宽度
let ZMSCREEN_WIDTH = UIScreen.main.bounds.width
/// 屏幕高度
let ZMSCREEN_HEIGHT = UIScreen.main.bounds.height

状态栏高度

状态栏的高度也同样重要,状态栏主要用于显示电池和信号信息,在刘海屏没有出现之前状态栏的高度固定为20点(points),这是iOS 7到iOS 10设备上的标准高度。

  • 在iPhone4/4S和iPhone 5/5S/5C:状态栏高度是20点。
  • iPhone6/6S/7/8(包括Plus版本)和其他早起iPhone模型:状态栏高度也是20点。
  • iPhone X及其之后型号(带有刘海屏):状态栏的高度增加到了44点,以适应刘海屏设计。

我们可以通过UIApplecation.shared.statusBarFrame.height来获取当前状态栏的高度。但是在iOS 13之后推荐使用UIViewController的viewSafeAreaInsets来处理与安全区域相关的布局。后面我们也会介绍到。

Swift 复制代码
/// 状态栏高度
var ZMSTATUSBAR_HEIGHT:CGFloat {
    get {
        if #available(iOS 13.0, *) {
            return UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        } else {
            return UIApplication.shared.statusBarFrame.height
        }
    }
}

顶部安全区域

在iOS开发中,顶部安全区域是指页面中从屏幕底部到底部安全区域之间的空间。自iPhone X引入刘海屏以来,状态栏不再仅仅占据20点的固定高度,而是随着设备的变化可能更高。在刘海屏设备(如iPhoneX、iPhone 11、iPhone 12等,包括iPhone 14以后的灵动岛)上,顶部安全区域的高度增加,用于容纳状态栏和刘海,通常是44点。而在没有刘海的设备上,顶部安全渔区的高度则保持20点。

因此,在适配不同屏幕是,开发这需要通过系统提供的安全区域属性safeAreaInsets来获取这些动态变化的安全区域,以确保UI元素不会被刘海或者状态栏遮挡。

Swift 复制代码
/// 顶部安全区域高度
var ZMTopSafeAreaHeight: CGFloat {
    get {
        return UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0
    }
}

底部安全区域

自从iPhone X开始,底部的物理Home键被移除,取而代之的是一个用于导航手势的区域,为了适配这一变化,底部安全区域(Safe Area Inset)应留出一定的空间,以防止手势操作与应用的UI元素冲突。不同设备的地步安全区域高度可能会有所不同,尤其是在全面屏设备上。

没有物理Home键的设备(如iPhone X及其之后的系列)上,底部安全区域会更大,通常为为34点,而在带有物理Home键的设备商,这个安全区域的高度为0。我们在设计界面时,必须考虑到这个底部安全区域。

可以通过safeAreaInsets.bottom来获取底部安全区域的高度。

Swift 复制代码
/// 底部安全区域高度
var ZMBottomSafeAreaHeight: CGFloat {
    get {
        return UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0
    }
}

导航栏高度

导航栏是iOS应用中最常见的UI组件之一,通常用于显示页面的标题、返回按钮等交互元素。在布局时,导航栏的高度是一个极其重要的参数。

在iPhone X出现之前,导航栏的高度是一个固定值,通常是44点,加上状态栏的高度20点。那么我们所看见的总高度就为64点。

iPhone X出现之后,状态栏的高度增肌了,虽然导航栏的核心部分依然保持44点的高度,但我们需要考虑状态栏的高度,其中状态栏约为44点,那么总高度通常为88点。

但是iPhone X之后我们还需要考虑安全区域的高度,因为这些设备的状态栏高度可能会随着安全区域的变化而有所不同,所以我们优先使用安全区域的topInset来确保正确布局。

Swift 复制代码
/// 导航栏高度()
var ZMNAVGATION_HEIGHT: CGFloat {
    guard let window = UIApplication.shared.windows.first else {
        return 0
    }

    let topSafeAreaInset = window.safeAreaInsets.top
    let navigationBarHeight = 44.0

    // 如果设备没有安全区域(即没有刘海),状态栏高度可能是 20
    if topSafeAreaInset > 0 {
        // 对于有刘海的设备,安全区域的 topInset 已经包含状态栏的高度
        return topSafeAreaInset + navigationBarHeight
    } else {
        // 没有刘海的设备,状态栏通常是 20,高度为状态栏 + 导航栏
        let statusBarHeight = UIApplication.shared.statusBarFrame.height
        return statusBarHeight + navigationBarHeight
    }
}

Tab Bar高度

Tab Bar的标准高度为49点,这是iPhone X之前所有设备上的固定高度。然而,自iPhone X引入全面屏设计并取消了物理Home键后,底部安全区域(Safe Area Inset)使得Tab Bar的高度在全面屏设备上有所增加。

因此我们需要通过计算底部底部安全区域的高度来动态设置Tab Bar的高度。

Swift 复制代码
/// tabbar高度
var ZMTABBAR_HEIGHT:CGFloat {
    get {
        return ZMBottomSafeAreaHeight + 49
    }
}

尺寸示例

下面我们就来打印几个机型的屏幕尺寸信息。

Swift 复制代码
        // 屏幕高
        print("屏幕高 = \(ZMSCREEN_HEIGHT)")
        // 屏幕宽
        print("屏幕宽 = \(ZMSCREEN_WIDTH)")
        // 状态栏高度
        print("状态栏高度 = \(ZMSTATUSBAR_HEIGHT)")
        // 顶部安全距离
        print("顶部安全距离 = \(ZMTopSafeAreaHeight)")
        // 底部安全距离
        print("底部安全距离 = \(ZMBottomSafeAreaHeight)")
        // 导航栏+安全距离
        print("导航栏+安全高度= \(ZMNAVGATION_HEIGHT)")
        // tabbar高度
        print("Tab Bar高度 = \(ZMTABBAR_HEIGHT)")

iPhone 15

屏幕高 = 852.0

屏幕宽 = 393.0

状态栏高度 = 54.0

顶部安全距离 = 59.0

底部安全距离 = 34.0

导航栏+安全高度= 103.0

Tab Bar高度 = 83.0

iPhone 11

屏幕高 = 896.0

屏幕宽 = 414.0

状态栏高度 = 48.0

顶部安全距离 = 48.0

底部安全距离 = 34.0

导航栏+安全高度= 92.0

Tab Bar高度 = 83.0

iPhone SE

屏幕高 = 667.0

屏幕宽 = 375.0

状态栏高度 = 20.0

顶部安全距离 = 20.0

底部安全距离 = 0.0

导航栏+安全高度= 64.0

Tab Bar高度 = 49.0

完整代码

Swift 复制代码
/// 屏幕宽度
let ZMSCREEN_WIDTH = UIScreen.main.bounds.width
/// 屏幕高度
let ZMSCREEN_HEIGHT = UIScreen.main.bounds.height
/// 状态栏高度
var ZMSTATUSBAR_HEIGHT:CGFloat {
    get {
        if #available(iOS 13.0, *) {
            return UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        } else {
            return UIApplication.shared.statusBarFrame.height
        }
    }
}

/// 顶部安全距离
var ZMTopSafeAreaHeight:CGFloat {
    get {
        return UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0
    }
}

/// 底部安全距离
var ZMBottomSafeAreaHeight:CGFloat {
    get {
        return UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0
    }
}

/// 导航栏高度()
var ZMNAVGATION_HEIGHT: CGFloat {
    guard let window = UIApplication.shared.windows.first else {
        return 0
    }

    let topSafeAreaInset = window.safeAreaInsets.top
    let navigationBarHeight = 44.0

    // 如果设备没有安全区域(即没有刘海),状态栏高度可能是 20
    if topSafeAreaInset > 0 {
        // 对于有刘海的设备,安全区域的 topInset 已经包含状态栏的高度
        return topSafeAreaInset + navigationBarHeight
    } else {
        // 没有刘海的设备,状态栏通常是 20,高度为状态栏 + 导航栏
        let statusBarHeight = UIApplication.shared.statusBarFrame.height
        return statusBarHeight + navigationBarHeight
    }
}

/// tabbar高度
var ZMTABBAR_HEIGHT:CGFloat {
    get {
        return ZMBottomSafeAreaHeight + 49
    }
}

结语

以上就是在iOS项目开发中关于屏幕尺寸以及导航栏高度Tab Bar高度适配的所有内容。通过动态获取屏幕尺寸、导航栏、状态栏和安全区域的高度,我们能够适配不同设备,确保应用在各种屏幕上都有最佳的用户体验。随着iPhone屏幕设计的演进,特别是全面屏和灵动岛的引入,开发者必须灵活运用这额布局方法,以适应不断变化的屏幕形态。

相关推荐
若水无华2 天前
fiddler 配置ios手机代理调试
ios·智能手机·fiddler
Aress"2 天前
【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
ios·uni-app·ipa安装
Jouzzy2 天前
【iOS安全】Dopamine越狱 iPhone X iOS 16.6 (20G75) | 解决Jailbreak failed with error
安全·ios·iphone
瓜子三百克2 天前
采用sherpa-onnx 实现 ios语音唤起的调研
macos·ios·cocoa
左钦杨2 天前
IOS CSS3 right transformX 动画卡顿 回弹
前端·ios·css3
努力成为包租婆2 天前
SDK does not contain ‘libarclite‘ at the path
ios
安和昂3 天前
【iOS】Tagged Pointer
macos·ios·cocoa
I烟雨云渊T3 天前
iOS 阅后即焚功能的实现
macos·ios·cocoa
struggle20253 天前
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
yolo·ios·开源·app·swift
Unlimitedz3 天前
iOS视频编码详细步骤(视频编码器,基于 VideoToolbox,支持硬件编码 H264/H265)
ios·音视频