随着iPhone X的发布,界面上变化最大的当属NavigationBar和TabBar,如果我们通过Frame定义视图的位置,则需判断设备类型是否为iPhone X,我们是否可以通过一种更优雅的方式,视图展示时不需要关心设备类型。
-
首先我们介绍几个iOS知识点
-
iOS 11 的 Safe Area
XIB勾选Use Safe Area Layout Guide最低支持的版本iOS9.0
屏幕快照 2017-11-07 下午3.24.35.png
代码方式实现SafeArea
@property (nonatomic,readonly) UIEdgeInsets safeAreaInsets API_AVAILABLE(ios(11.0),tvos(11.0));
image.png-
Top Layout Guide 和 Bottom Layout Guide
topLayoutGuide.length:表示当前页面的上方被status bar、navigation bar遮挡的部分,对应safeAreaInsets.top
bottomLayoutGuide.length:表示当前页面的下方被TabBar、ToolBar遮挡的部分,对应safeAreaInsets.bottom
这两个属性属于ViewController
-
-
实现
-
思路
是否我们可以给UIViewController增加一个视图(ContentView),ContentView根据SafeArea自动适应,其它的视图添加到ContentView,这样就不需要关心导航栏和TabBar的高度
创建基类ViewController,ViewController添加一个视图,该视图针对SafeArea做好约束条件,项目中所有的Controller都继承这个类,这种方式侵入性太强
通过Category的方式,UIViewController增加一个视图属性,当Controller中添加视图时,都增加到Category类中的这个视图上,这种方式,如果用户不调用Category增加的视图,不对Controller有任何影响
-
代码
-
UIViewController+SafeArea.h
@interface UIViewController (SafeArea)
@property (nonatomic, strong) UIView *contentView;
@end
#import "UIViewController+SafeArea.h"
#import <objc/runtime.h>
#import "Masonry.h"
static const void *ContentView = &ContentView;
@implementation UIViewController (SafeArea)
- (void)setContentView:(UIView *)contentView {
objc_setAssociatedObject(self, ContentView, contentView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)contentView {
UIView *view = objc_getAssociatedObject(self, ContentView);
if (!view) {
view = [UIView new];
view.backgroundColor = [UIColor clearColor];
self.contentView = view;
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.equalTo(self.view);
if (@available(iOS 11.0, *)) {
make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
make.top.equalTo(self.mas_topLayoutGuide);
make.bottom.equalTo(self.mas_bottomLayoutGuide);
}
}];
}
return view;
}
@end
-
使用
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"SafeArea";
[self.contentView addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.and.right.equalTo(self.contentView);
}];
}
注意如果项目首页展示UICollectionView,启动页状态栏默认隐藏,这时候再进入到首页UICollectionView中的cell展示出现问题,我们需要特殊处理
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.collectionView.collectionViewLayout invalidateLayout];
}
完整的使用例子可以参考:
https://github.com/cheyongzi/SafeArea
觉得还不错的可以给个Star