iOS11 & iPhone XiOS11 及 iPhoneX 适配iOS11

iPhoneX适配

2017-11-22  本文已影响197人  远辰jt

1. 屏幕大小

iPhoneX屏幕大小为375x812个点,相比于iPhone6和7的375x667个点 在垂直方向上多出145个点,需要注意的是坐标系的原点为方框的左上角,也就意味着如果代码给控件设置绝对frame有可能会被四周圆角或者顶部的摄像头区域给切掉。 图1坐标系.png

2. 各种高度改变

iPhoneX的状态栏高度由之前的20个点变为44个点(如图2状态栏和导航栏) 图2状态栏和导航栏.png
导航栏的高度默认情况下还是44,iOS11之后新增大标题模式,largeTitle开启的情况导航栏高度是96,除去原有的高度在下面多出了52个点高度的显示大标题的地方。(图3大标题模式) 图3大标题模式.png
tabBar的高度没有变 依旧是49,不过在tabBar下面还有一个高度为34的带圆角的区域,这个区域中包含HomeIndicator提供给用户返回Home和唤出多任务的功能。

3. safeArea

iOS11新增safeArea的概念就是苹果为了给开发者提供一个适配和开发的准则, 安全区域就是能够正常有效的显示视图并和用户交互的区域,区域大小并不是固定的 而是根据控制器否有导航栏、状态栏、tabBar、ToolBar动态改变的。 原则上所有非滚动试图都应该显示在安全区域内以保证正确的显示和交互。竖屏安全区域 (图4竖屏安全区域) 图4竖屏安全区域.png
和横屏下的安全区域 (图5横屏安全区域) 图5横屏安全区域.png

4. 检查自己的应用哪些地方需要适配

Xcode9带有iPhoneX的模拟器,可以在上面运行查看自己应用的显示情况,如果发现自己的app在X下运行时上下都有黑条,那是因为应用在启动的时候没有对应的启动图,所以需要添加在X下运行的@3X的1125X2436px大小的启动图,准备好启动图后showInFinder放到启动图文件夹下,然后在Contents.json中添加对应的描述即可

{
      "extent" : "full-screen",
      "idiom" : "iphone",
      "subtype" : "2436h",
      "filename" : "0b1@2x-1.png",
      "minimum-system-version" : "11.0",
      "orientation" : "portrait",
      "scale" : "3x"
    },

注意filename是你启动图的名字,如果添加后Contents.json的格式不正确,可以新建一个lanchImage,新建的lanchImage文件夹下的Contents.json带有iPhoneX启动图的描述, 然后在新建的lanchImage中找到Contents.json文件中的相关描述复制过来即可。

5. 界面的适配

应用大部分都是竖屏界面,先说说竖屏界面的适配.

#define  ScreenWidth   [UIScreen mainScreen].bounds.size.width
#define  ScreenHeight  [UIScreen mainScreen].bounds.size.height
#define  iPhoneX (ScreenWidth == 375.f && ScreenHeight == 812.f ? YES : NO)
#define  StatusBarHeight      (iPhoneX ? 44.f : 20.f)
#define  NavigationBarHeight  44.f
#define  TabbarHeight         (iPhoneX ? (49.f+34.f) : 49.f)
#define  TabbarSafeBottomMargin         (iPhoneX ? 34.f : 0.f)

#define  LanscapeLeftMargin         (iPhoneX ? 44.f : 0.f)
#define  LanscapeRightMargin         (iPhoneX ? 44.f : 0.f)
#define  LanscapeBottomMargin         (iPhoneX ? 0.f : 0.f)

6. 导航栏的适配

在iOS11下导航栏左边和右边item的位置发生了变化,左边的往右移动了一段距离,而右边的往左移动了一段距离,好像是20个点。而在iOS11之前内边距也是存在的,但是大部分都是加了一个负距离的FixedSpace的适配好了。但是在iOS11中 导航栏的结构发生了变化,(如图7导航栏结构)在iOS11下就会出现偏移距离的问题。怎么解决呢? 图7导航栏结构.png
  1. 给leftButton设置x值为-20 ? 测试后发现ButtonBarStackView的大小和button的大小一样,但是位置没有变化。并且即使这样button的位置起作用了,超出父控件的部分不能接收事件。

  2. 能不能在控制器的view显示之前遍历navigationbar的子控件拿到UIButtonBarStackView,然后改变其约束呢? 我把遍历的代码写在viewWillAppear中 发现遍历后打印的数组是空的,放在didAppear中遍历就有了,但是这样不行 因为在DidAppear中重新设置UIButtonBarStackView的位置的话,控制器显示后可以看到button的移动 🤣

  3. 可以设置button的内容偏移contentEdgeInsets 让按钮的内容往左或者往右偏移20 的距离,但是会出现用户点击返回按钮但是没有反应的情况。可以重写navigationBar 的hitTest方法 判断点击的位置如果是左边的button就让左边的button接受事件,右边的同理。怎样重写UINavigationBar的方法呢 一种是继承然后重写,但是这种明显不适合系统控件,第二种就是给UINavigationBar添加分类 然后在分类中重写hitTest方法 然后判断点击的位置是左边的还是右边的,返回对应的button即可

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
   UIView *view = [super hitTest:point withEvent:event];
   if (point.x < [UIScreen mainScreen].bounds.size.width * 0.5) {

       for (UIBarButtonItem *item in self.topItem.leftBarButtonItems) {
           if (item.customView == nil) {
               continue;
           }
           if ([item.customView isKindOfClass:[HitButton class]]) {
               HitButton *leftButton = (HitButton *)item.customView;
               CGRect newRect = [leftButton convertRect:leftButton.hitFrame toView:self];
               if (CGRectContainsPoint(newRect, point)) {
                   view = leftButton;
                   break;
               }
           }
       }
   }else{
       for (UIBarButtonItem *item in self.topItem.rightBarButtonItems) {
           if (item.customView == nil) {
               continue;
           }
           if ([item.customView isKindOfClass:[HitButton class]]) {
               HitButton *rightButton = (HitButton *)item.customView;
               CGRect newRect = [rightButton convertRect:rightButton.hitFrame toView:self];
               if (CGRectContainsPoint(newRect, point)) {
                   view = rightButton;
                   break;
               }
           }
       }
   }
   return view;
}

7. tableView的适配

@property (nonatomic) CGFloat rowHeight;             // default is UITableViewAutomaticDimension
@property (nonatomic) CGFloat sectionHeaderHeight;   // default is UITableViewAutomaticDimension
@property (nonatomic) CGFloat sectionFooterHeight;   // default is UITableViewAutomaticDimension
@property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
@property (nonatomic) CGFloat estimatedSectionHeaderHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
@property (nonatomic) CGFloat estimatedSectionFooterHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable

8. 视频横屏播放适配

上一篇下一篇

猜你喜欢

热点阅读