服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - 详解iOS11、iPhone X、Xcode9 适配指南

详解iOS11、iPhone X、Xcode9 适配指南

2021-03-30 16:25si1ence IOS

这篇文章主要介绍了详解iOS11、iPhone X、Xcode9 适配指南,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

更新ios11后,发现有些地方需要做适配,整理后按照优先级分为以下三类:

  • 单纯升级ios11后造成的变化;
  • xcode9 打包后造成的变化;
  • iphonex的适配

一、单纯升级ios11后造成的变化

升级后,发现某个拥有tableview的界面错乱,组间距和contentinset错乱,因为ios11中 uiviewcontroller 的 automaticallyadjustsscrollviewinsets 属性被废弃了,因此当tableview超出安全区域时,系统自动会调整safeareainsets值,进而影响adjustedcontentinset值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 有些界面以下使用代理方法来设置,发现并没有生效
- (cgfloat)tableview:(uitableview *)tableview heightforheaderinsection:(nsinteger)section;
- (cgfloat)tableview:(uitableview *)tableview heightforfooterinsection:(nsinteger)section;
 
// 这样的原理是因为之前只是实现了高度的代理方法,却没有实现view的代理方法,ios10及以前这么写是没问题的,ios11开启了行高估算机制引起的bug,因此有以下几种解决方法:
 
// 解决方法一:添加实现view的代理方法
- (uiview *)tableview:(uitableview *)tableview viewforfooterinsection:(nsinteger)section {
  return nil;
}
- (uiview *)tableview:(uitableview *)tableview viewforheaderinsection:(nsinteger)section {
  return nil;
}
 
// 解决方法二:直接使用tableview属性进行设置,修复该ui错乱
self.tableview.sectionheaderheight = 0;
self.tableview.sectionfooterheight = 5;
 
[_optiontableview setcontentinset:uiedgeinsetsmake(-35, 0, 0, 0)];
 
// 解决方法三:添加以下代码关闭估算行高
self.tableview.estimatedrowheight = 0;
self.tableview.estimatedsectionheaderheight = 0;
self.tableview.estimatedsectionfooterheight = 0;

四、使用xcode9 编译后发现的问题

1. 发现“fastsocket”第三方报错,具体原因是缺少c99的头文件,引入“#include <sys/time.h>”即可

详解iOS11、iPhone X、Xcode9 适配指南
2. 导航栏的新特性

原生的搜索栏样式发生改变

详解iOS11、iPhone X、Xcode9 适配指南

右边为ios11样式,搜索区域高度变大,字体变大

查看 api 后发现,ios11后将 searchcontroller 赋值给了 navigationitem,通过属性 hidessearchbarwhenscrolling 可以控制搜索栏是否在滑动的时候进行隐藏和显示

?
1
2
3
4
// a view controller that will be shown inside of a navigation controller can assign a uisearchcontroller to this property to display the search controller's search bar in its containing navigation controller's navigation bar.
@property (nonatomic, retain, nullable) uisearchcontroller *searchcontroller api_available(ios(11.0)) api_unavailable(tvos);
 
// if this property is true (the default), the searchcontroller's search bar will hide as the user scrolls in the top view controller's scroll view. if false, the search bar will remain visible and pinned underneath the navigation bar.

另外,uinavigationbar 新增属性 bool值 preferslargetitles 来实现下面的效果,并可以通过 largetitletextattributes 来设置大标题的文本样式

详解iOS11、iPhone X、Xcode9 适配指南

有个界面使用到了导航栏按钮相关的frame,也发生了ui错乱,查看ui层级关系后发现,ios11以前是直接把按钮加到了uinavigationbar上面,而ios11则是先将按钮加到了_uitamicadaptorview,再加到_uibuttonbarstackview、_uinavigationbarcontentview,接着才是uinavigationbar。因此如果需要获取导航栏按钮 frame 或者 superview,这里需要专门做下适配

详解iOS11、iPhone X、Xcode9 适配指南

ios10及以下版本导航栏按钮层级关系图

详解iOS11、iPhone X、Xcode9 适配指南

ios11导航栏按钮层级关系图

三、iphone x的适配

下载完xcode9之后,第一件事自然是在 iphone x(模拟器)上过把瘾,然后编译后就发现报错了

由于iphone x的状态栏是和其他版本手机差异比较大的,因此api 变化也比较大

先后做了以下适配

适配点一:项目中使用状态栏中图标判断当前网络的具体状态

详解iOS11、iPhone X、Xcode9 适配指南
出错代码

打印的 log 报出以下错误: trapped uncaught exception 'nsunknownkeyexception', reason: '[<uistatusbar_modern 0x7fcdb0805770> valueforundefinedkey:]: this class is not key value coding-compliant for the key foregroundview.'

详解iOS11、iPhone X、Xcode9 适配指南

iphone x

详解iOS11、iPhone X、Xcode9 适配指南

其他手机

使用 runtime 打印其所有属性,发现以下差异

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 测试代码
#import <objc/runtime.h>
nsmutablestring *resultstr = [nsmutablestring string];
//获取指定类的ivar列表及ivar个数
unsigned int count = 0;
ivar *member = class_copyivarlist([[application valueforkeypath:@"_statusbar"] class], &count);
  
for(int i = 0; i < count; i++){
  ivar var = member[i];
  //获取ivar的名称
  const char *memberaddress = ivar_getname(var);
  //获取ivar的类型
  const char *membertype = ivar_gettypeencoding(var);
  nsstring *str = [nsstring stringwithformat:@"key = %s       type = %s \n",memberaddress,membertype];
   [resultstr appendstring:str];
}
nslog(@"%@", resultstr);
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 其他版本的手机
key = _inprocessprovider      type = @"<uistatusbarstateprovider>"
key = _showsforeground       type = b
key = _backgroundview        type = @"uistatusbarbackgroundview"
key = _doubleheightlabel      type = @"uilabel"
key = _doubleheightlabelcontainer  type = @"uiview"
key = _currentdoubleheighttext   type = @"nsstring"
key = _currentrawdata        type = {超长。。}
key = _interruptedanimationcompositeviews type = @"nsmutablearray"
key = _newstylebackgroundview    type = @"uistatusbarbackgroundview"
key = _newstyleforegroundview    type = @"uistatusbarforegroundview"
key = _slidingstatusbar       type = @"uistatusbar"
key = _styleattributes       type = @"uistatusbarstyleattributes"
key = _waitingoncallbackafterchangingstyleoverrideslocally type = b
key = _suppressglow         type = b
key = _translucentbackgroundalpha  type = d
key = _showonlycenteritems     type = b
key = _foregroundviewshouldignorestatusbardataduringanimation type = b
key = _tintcolor          type = @"uicolor"
key = _lastusedbackgroundcolor   type = @"uicolor"
key = _nexttinttransition      type = @"uistatusbarstyleanimationparameters"
key = _overrideheight        type = @"nsnumber"
key = _disablerasterizationreasons type = @"nsmutableset"
key = _timehidden          type = b
key = _statusbarwindow       type = @"uistatusbarwindow"
 
// iphone x
key = _statusbar ; type = @"_uistatusbar"
 
// 因此可见iphone x的状态栏是多嵌套了一层,多取一次即可,最终适配代码为:
nsarray *children;
// 不能用 [[self deviceversion] isequaltostring:@"iphone x"] 来判断,因为模拟器不会返回 iphone x
  if ([[application valueforkeypath:@"_statusbar"] iskindofclass:nsclassfromstring(@"uistatusbar_modern")]) {
    children = [[[[application valueforkeypath:@"_statusbar"] valueforkeypath:@"_statusbar"] valueforkeypath:@"foregroundview"] subviews];
  } else {
    children = [[[application valueforkeypath:@"_statusbar"] valueforkeypath:@"foregroundview"] subviews];
  }

适配点二:解决这个问题后项目跑起来发现,整个app界面上下各空出大概40pt的高度

详解iOS11、iPhone X、Xcode9 适配指南

经常从 github 上下载项目把玩的老司机们都知道,有些老项目在模拟器上跑起来之后也会只有 iphone 4(320*480)的布局空间,造成这个的原因是启动图使用 launch images source 设置的时候没有勾选并设置对应的图片,解决方法如下

 

详解iOS11、iPhone X、Xcode9 适配指南

然而iphone x更大的坑是屏幕的适配

首先看下屏幕尺寸

详解iOS11、iPhone X、Xcode9 适配指南

这张图反映出不少信息:

  • iphone x的宽度虽然和7是一样的,但是高度多出145pt
  • 使用三倍图是重点,而且一般认为肉眼所能所能识别的最高的屏幕密度是300ppi,iphone x已达到458ppi(查证发现三星galaxy系列的屏幕密度是522ppi)

在设计方面,苹果官方文档human-interface-guidelines有明确要求,下面结合图例进行说明:

详解iOS11、iPhone X、Xcode9 适配指南

展示出来的设计布局要求填满整个屏幕

详解iOS11、iPhone X、Xcode9 适配指南

填满的同时要注意控件不要被大圆角和传感器部分所遮挡

详解iOS11、iPhone X、Xcode9 适配指南

安全区域以外的部分不允许有任何与用户交互的控件

上面这张图内含信息略多

头部导航栏不予许进行用户交互的,意味着下面这两种情况 apple 官方是不允许的

详解iOS11、iPhone X、Xcode9 适配指南

详解iOS11、iPhone X、Xcode9 适配指南

  • 底部虚拟区是替代了传统home键,高度为34pt,通过上滑可呼起多任务管理,考虑到手势冲突,这部分也是不允许有任何可交互的控件
  • 状态栏在非安全区域,文档中也提到,除非可以通过隐藏状态栏给用户带来额外的价值,否则最好把状态栏还给用户

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.jianshu.com/p/f5ee206c7df0

延伸 · 阅读

精彩推荐
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25