随着 iPhone 手机的设备设计逐渐变更,刘海屏和灵动岛(Dynamic Island)成为了重要的 UI 适配需求。为了保证应用在这些设备上的良好用户体验,我们IOS的开发者需要在应用中进行相应的适配。
本文将详细介绍如何在 iOS 应用中使用 Objective-C 适配刘海屏与灵动岛,包括如何调整视图布局、处理安全区域(safe area)等关键要点。
适配设备
- 刘海屏(Notch) :主要指 iPhone X 及之后的设备,顶部有一个“刘海”区域,用于放置前置摄像头和传感器。
- 灵动岛(Dynamic Island) :自 iPhone 14 Pro 起引入,屏幕顶部有一个动态变化的交互区域,取代了传统的刘海区域。
在这两种设备上,开发者需要特别处理顶部视图与内容区域的适配,确保 UI 不会被遮挡,并且能够兼容不同的屏幕形态。
适配步骤
一、获取设备状态
首先,我们需要检查设备是否为刘海屏或灵动岛设备。可以使用 hasNotch 和 isDynamicIsland 来判断当前设备的屏幕类型。
#import <UIKit/UIKit.h>
@interface DeviceHelper : NSObject
+ (BOOL)hasNotch;
+ (BOOL)isDynamicIsland;
@end
@implementation DeviceHelper
// 判断是否为刘海屏(iPhone X及以后)
+ (BOOL)hasNotch {
if (@available(iOS 11.0, *)) {
UIWindow *window = [UIApplication sharedApplication].windows.firstObject;
return window.safeAreaInsets.top > 20.0;
}
return NO;
}
// 判断是否为灵动岛设备(iPhone 14 Pro及以后)
+ (BOOL)isDynamicIsland {
if (@available(iOS 16.0, *)) {
return [self hasNotch] && [UIScreen mainScreen].nativeBounds.size.height > 2000; // 具体尺寸可以根据实际设备调整
}
return NO;
}
@end
二、处理安全区域(Safe Area)
在刘海屏和灵动岛设备上,视图的顶部、底部、左右两侧都有可能被遮挡。为了避免视图内容被刘海、灵动岛或者设备底部的 Home Bar 遮挡,我们可以使用 安全区域(Safe Area)来布局。
获取和设置安全区域:
// 获取当前设备的安全区域
UIEdgeInsets safeAreaInsets = self.view.safeAreaInsets;
// 设置视图的顶部间距(避开刘海或灵动岛区域)
CGFloat topMargin = safeAreaInsets.top;
CGFloat bottomMargin = safeAreaInsets.bottom;
// 设置视图布局
CGRect frame = CGRectMake(0, topMargin, self.view.bounds.size.width, self.view.bounds.size.height - topMargin - bottomMargin);
使用自动布局(Auto Layout)适配安全区域:
// 使用Auto Layout设置顶部视图(例如:UILabel)
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:titleLabel];
// 设置约束
[NSLayoutConstraint activateConstraints:@[
[titleLabel.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[titleLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],
[titleLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20]
]];
三、处理灵动岛(Dynamic Island)
灵动岛是一个动态区域,可能显示多种信息,开发者在进行 UI 布局时,需要考虑该区域的高度。可以通过获取安全区域的顶部间距来动态调整视图。
判断设备类型并动态调整视图布局:
if ([DeviceHelper isDynamicIsland]) {
// 如果是灵动岛设备,灵动岛区域有较大的动态显示空间
// 获取灵动岛的动态区域高度
CGFloat dynamicIslandHeight = 30.0; // 根据设备模型动态调整
// 设置顶部视图间距
CGRect frame = CGRectMake(0, dynamicIslandHeight, self.view.bounds.size.width, self.view.bounds.size.height - dynamicIslandHeight);
self.view.frame = frame;
}
使用灵动岛时的适配建议:
- 避免直接覆盖灵动岛区域:确保视图内容不会直接覆盖灵动岛区域,可以通过调整顶部视图的位置来避开。
- 使用动画优化体验:灵动岛区域具有动态变化,因此可以利用动画使得 UI 在灵动岛状态下变化更为平滑和自然。
适配技巧与优化
1. 在不同设备上自适应布局
为了确保布局在不同屏幕尺寸和屏幕类型的设备上都能良好显示,可以使用 Auto Layout(自动布局)进行适配。通过 safeAreaLayoutGuide 和设置 priority,可以确保视图自适应。
2. 动态调整视图区域
使用动态计算视图位置的方式,确保视图不会被刘海或者灵动岛区域遮挡。例如:
CGFloat topMargin = self.view.safeAreaInsets.top;
CGFloat dynamicIslandHeight = 0.0;
if ([DeviceHelper isDynamicIsland]) {
dynamicIslandHeight = 30.0; // 灵动岛设备的动态区域高度
}
// 计算视图的顶部位置
CGRect newFrame = CGRectMake(0, topMargin + dynamicIslandHeight, self.view.bounds.size.width, self.view.bounds.size.height - topMargin - dynamicIslandHeight);
3. 注意屏幕旋转适配
刘海屏和灵动岛设备的适配不仅仅是横屏和竖屏的切换,还要处理屏幕旋转时的布局变化。确保在 viewWillTransitionToSize: 中重新计算视图的安全区域。
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// 更新视图布局,重新计算安全区域
[self updateLayoutForNewOrientation];
}
- (void)updateLayoutForNewOrientation {
CGFloat topMargin = self.view.safeAreaInsets.top;
// 重新设置视图的顶部间距
}
最后
本文张介绍了如何在 iOS 中使用 Objective-C 适配刘海屏与灵动岛设备。通过使用安全区域和动态计算布局,开发者可以确保应用的 UI 在这些设备上显示良好,避免内容被刘海或灵动岛区域遮挡。
对于支持刘海屏、灵动岛的设备,建议使用 Auto Layout 和 safeAreaInsets 来处理视图布局,同时要注意动态调整视图位置,以提供最佳的用户体验。
如有说错的地方,烦请大家指正,一起进步~