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

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

服务器之家 - 编程语言 - IOS - iOS10适配问题及解决方法 新鲜出炉!

iOS10适配问题及解决方法 新鲜出炉!

2021-02-01 16:15Eternaldream IOS

这篇文章主要为大家详细介绍了iOS 10适配问题,总结了一些关于iOS10适配方面的问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随着ios10发布的临近,大家的app都需要适配ios10,下面是我总结的一些关于ios10适配方面的问题,如果有错误,欢迎指出.

1.系统判断方法失效:
在你的项目中,当需要判断系统版本的话,不要使用下面的方法:

 

复制代码 代码如下:
#define isios10 ([[[[uidevice currentdevice] systemversion] substringtoindex:1] intvalue]>=10)

 

 

它会永远返回no,substringtoindex:1在ios 10 会被检测成 ios 1了,
应该使用下面的这些方法:

objective-c 中这样写:

?
1
2
3
4
5
#define system_version_equal_to(v) ([[[uidevice currentdevice] systemversion] compare:v options:nsnumericsearch] == nsorderedsame)
#define system_version_greater_than(v) ([[[uidevice currentdevice] systemversion] compare:v options:nsnumericsearch] == nsordereddescending)
#define system_version_greater_than_or_equal_to(v) ([[[uidevice currentdevice] systemversion] compare:v options:nsnumericsearch] != nsorderedascending)
#define system_version_less_than(v) ([[[uidevice currentdevice] systemversion] compare:v options:nsnumericsearch] == nsorderedascending)
#define system_version_less_than_or_equal_to(v) ([[[uidevice currentdevice] systemversion] compare:v options:nsnumericsearch] != nsordereddescending)

或者使用:

 

复制代码 代码如下:
if ([[nsprocessinfo processinfo] isoperatingsystematleastversion:(nsoperatingsystemversion){.majorversion = 9, .minorversion = 1, .patchversion = 0}]) { nslog(@"hello from > ios 9.1");}
if ([nsprocessinfo.processinfo isoperatingsystematleastversion:(nsoperatingsystemversion){9,3,0}]) { nslog(@"hello from > ios 9.3");}

 

或者使用:

 

复制代码 代码如下:
if (nsfoundationversionnumber > nsfoundationversionnumber_ios_9_0) { // do stuff for ios 9 and newer} else { // do stuff for older versions than ios 9}

 

有时候会缺少一些常量,nsfoundationversionnumber是在nsobjcruntime.h中定义的,作为xcode7.3.1的一部分,我们设定常熟范围从iphone os 2到#define nsfoundationversionnumber_ios_8_4 1144.17,在ios 10(xcode 8)中,苹果补充了缺少的数字,设置有未来的版本.

?
1
2
3
4
5
6
#define nsfoundationversionnumber_ios_9_0 1240.1
#define nsfoundationversionnumber_ios_9_1 1241.14
#define nsfoundationversionnumber_ios_9_2 1242.12
#define nsfoundationversionnumber_ios_9_3 1242.12
#define nsfoundationversionnumber_ios_9_4 1280.25
#define nsfoundationversionnumber_ios_9_x_max 1299

swift中这样写:

?
1
2
3
if nsprocessinfo().isoperatingsystematleastversion(nsoperatingsystemversion(majorversion: 10, minorversion: 0, patchversion: 0)) {
  // 代码块
}

或者使用

?
1
2
3
4
5
if #available(ios 10.0, *) {
  // 代码块
} else {
  // 代码块
}

2.隐私数据访问问题:

你的项目中访问了隐私数据,比如:相机,相册,联系人等,在xcode8中打开编译的话,统统会crash,控制台会输出下面这样的日志:

iOS10适配问题及解决方法 新鲜出炉!

这是因为ios对用户的安全和隐私的增强,在申请很多私有权限的时候都需要添加描述,但是,在使用xcode 8之前的xcode还是使用系统的权限通知框.
要想解决这个问题,只需要在info.plist添加nscontactsusagedescription的key, value自己随意填写就可以,这里列举出对应的key(source code模式下):

?
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
38
<!-- 相册 -->
<key>nsphotolibraryusagedescription</key>
<string>app需要您的同意,才能访问相册</string>
<!-- 相机 -->
<key>nscamerausagedescription</key>
<string>app需要您的同意,才能访问相机</string>
<!-- 麦克风 -->
<key>nsmicrophoneusagedescription</key>
<string>app需要您的同意,才能访问麦克风</string>
<!-- 位置 -->
<key>nslocationusagedescription</key>
<string>app需要您的同意,才能访问位置</string>
<!-- 在使用期间访问位置 -->
<key>nslocationwheninuseusagedescription</key>
<string>app需要您的同意,才能在使用期间访问位置</string>
<!-- 始终访问位置 -->
<key>nslocationalwaysusagedescription</key>
<string>app需要您的同意,才能始终访问位置</string>
<!-- 日历 -->
<key>nscalendarsusagedescription</key>
<string>app需要您的同意,才能访问日历</string>
<!-- 提醒事项 -->
<key>nsremindersusagedescription</key>
<string>app需要您的同意,才能访问提醒事项</string>
<!-- 运动与健身 -->
<key>nsmotionusagedescription</key> <string>app需要您的同意,才能访问运动与健身</string>
<!-- 健康更新 -->
<key>nshealthupdateusagedescription</key>
<string>app需要您的同意,才能访问健康更新 </string>
<!-- 健康分享 -->
<key>nshealthshareusagedescription</key>
<string>app需要您的同意,才能访问健康分享</string>
<!-- 蓝牙 -->
<key>nsbluetoothperipheralusagedescription</key>
<string>app需要您的同意,才能访问蓝牙</string>
<!-- 媒体资料库 -->
<key>nsapplemusicusagedescription</key>
<string>app需要您的同意,才能访问媒体资料库</string>

如果不起作用,可以请求后台权限,类似于这样:

?
1
2
3
4
5
6
<key>uibackgroundmodes</key>
<array>
<!-- 在这里写上你在后台模式下要使用权限对应的key -->
<string>location</string>
...
</array>

或者在xcode里选中当前的target,选择capabilities,找到background modes,打开它,在里面选择对应权限

iOS10适配问题及解决方法 新鲜出炉!

3.uicolor的问题

官方文档中说:大多数core开头的图形框架和avfoundation都提高了对扩展像素和宽色域色彩空间的支持.通过图形堆栈扩展这种方式比以往支持广色域的显示设备更加容易。现在对uikit扩展可以在srgb的色彩空间下工作,性能更好,也可以在更广泛的色域来搭配srgb颜色.如果你的项目中是通过低级别的api自己实现图形处理的,建议使用srgb,也就是说在项目中使用了rgb转化颜色的建议转换为使用srgb,在uicolor类中新增了两个api:

?
1
2
- (uicolor *)initwithdisplayp3red:(cgfloat)displayp3red green:(cgfloat)green blue:(cgfloat)blue alpha:(cgfloat)alpha ns_available_ios(10_0);
+ (uicolor *)colorwithdisplayp3red:(cgfloat)displayp3red green:(cgfloat)green blue:(cgfloat)blue alpha:(cgfloat)alpha ns_available_ios(10_0);

4.真彩色的显示

真彩色的显示会根据光感应器来自动的调节达到特定环境下显示与性能的平衡效果,如果需要这个功能的话,可以在info.plist里配置(在source code模式下):

<key>uiwhitepointadaptivitystyle</key>
它有五种取值,分别是:

?
1
2
3
4
5
<string>uiwhitepointadaptivitystylestandard</string> // 标准模式
<string>uiwhitepointadaptivitystylereading</string> // 阅读模式
<string>uiwhitepointadaptivitystylephoto</string> // 图片模式
<string>uiwhitepointadaptivitystylevideo</string> // 视频模式
<string>uiwhitepointadaptivitystylestandard</string> // 游戏模式

也就是说如果你的项目是阅读类的,就选择uiwhitepointadaptivitystylereading这个模式,五种模式的显示效果是从上往下递减,也就是说如果你的项目是图片处理类的,你选择的是阅读模式,给选择太好的效果会影响性能.

5.ats的问题

1.在ios 9的时候,默认非htts的网络是被禁止的,我们可以在info.plist文件中添加nsapptransportsecurity字典,将nsallowsarbitraryloads设置为yes来禁用ats;
2.从2017年1月1日起,,所有新提交的 app 默认不允许使用nsallowsarbitraryloads来绕过ats的限制,默认情况下你的 app 可以访问加密足够强的(tls v1.2以上)https内容;
3.可以选择使用nsexceptiondomains设置白名单的方式对特定的域名开放http内容来通过审核,比如说你的应用集成了第三方的登录分享sdk,可以通过这种方式来做,下面以新浪sdk作为示范(source code 模式下):

?
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<key>nsapptransportsecurity</key>
<dict>
<key>nsexceptiondomains</key>
<dict>
<key>sina.cn</key>
<dict>
<key>nsthirdpartyexceptionminimumtlsversion</key>
<string>tlsv1.0</string>
<key>nsthirdpartyexceptionrequiresforwardsecrecy</key>
<false/>
<key>nsincludessubdomains</key>
<true/>
</dict>
<key>weibo.cn</key>
<dict>
<key>nsthirdpartyexceptionminimumtlsversion</key>
<string>tlsv1.0</string>
<key>nsthirdpartyexceptionrequiresforwardsecrecy</key>
<false/>
<key>nsincludessubdomains</key>
<true/>
</dict>
<key>weibo. com</key>
<dict>
<key>nsthirdpartyexceptionminimumtlsversion</key>
<string>tlsv1.0</string>
<key>nsthirdpartyexceptionrequiresforwardsecrecy</key>
<false/>
<key>nsincludessubdomains</key>
<true/>
</dict>
<key>sinaimg.cn</key>
<dict>
<key>nsthirdpartyexceptionminimumtlsversion</key>
<string>tlsv1.0</string>
<key>nsthirdpartyexceptionrequiresforwardsecrecy</key>
<false/>
<key>nsincludessubdomains</key>
<true/>
</dict>
<key>sinajs.cn</key>
<dict>
<key>nsthirdpartyexceptionminimumtlsversion</key>
<string>tlsv1.0</string>
<key>nsthirdpartyexceptionrequiresforwardsecrecy</key>
<false/>
<key>nsincludessubdomains</key>
<true/>
</dict>
<key>sina.com.cn</key>
<dict>
<key>nsthirdpartyexceptionminimumtlsversion</key>
<string>tlsv1.0</string>
<key>nsthirdpartyexceptionrequiresforwardsecrecy</key>
<false/>
<key>nsincludessubdomains</key>
<true/>
</dict>
</dict>
</dict>

4.在ios 10 中info.plist文件新加入了nsallowsarbitraryloadsinwebcontent键,允许任意web页面加载,同时苹果会用 ats 来保护你的app;
5.安全传输不再支持sslv3, 建议尽快停用sha1和3des算法;

6.uistatusbar的问题:
在ios10中,如果还使用以前设置uistatusbar类型或者控制隐藏还是显示的方法,会报警告,方法过期,如下图:

iOS10适配问题及解决方法 新鲜出炉!

上面方法到 ios 10 不能使用了,要想修改uistatusbar的样式或者状态使用下图中所示的属性或方法:

?
1
2
3
4
5
6
@property(nonatomic, readonly) uistatusbarstyle preferredstatusbarstyle ns_available_ios(7_0) __tvos_prohibited; // defaults to uistatusbarstyledefault
@property(nonatomic, readonly) bool prefersstatusbarhidden ns_available_ios(7_0) __tvos_prohibited; // defaults to no
- (uistatusbarstyle)preferredstatusbarstyle ns_available_ios(7_0) __tvos_prohibited; // defaults to uistatusbarstyledefault
- (bool)prefersstatusbarhidden ns_available_ios(7_0) __tvos_prohibited; // defaults to no
// override to return the type of animation that should be used for status bar changes for this view controller. this currently only affects changes to prefersstatusbarhidden.
- (uistatusbaranimation)preferredstatusbarupdateanimation ns_available_ios(7_0) __tvos_prohibited; // defaults to uistatusbaranimationfade

7.uitextfield

在ios 10 中,uitextfield新增了textcontenttype字段,是uitextcontenttype类型,它是一个枚举,作用是可以指定输入框的类型,以便系统可以分析出用户的语义.是电话类型就建议一些电话,是地址类型就建议一些地址.可以在#import <uikit/uitextinputtraits.h>文件中,查看textcontenttype字段,有以下可以选择的类型:

uikit_extern uitextcontenttype const uitextcontenttypename                      ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypenameprefix                ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypegivenname                 ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypemiddlename                ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypefamilyname                ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypenamesuffix                ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypenickname                  ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypejobtitle                  ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypeorganizationname          ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypelocation                  ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypefullstreetaddress         ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypestreetaddressline1        ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypestreetaddressline2        ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypeaddresscity               ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypeaddressstate              ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypeaddresscityandstate       ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypesublocality               ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypecountryname               ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypepostalcode                ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypetelephonenumber           ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypeemailaddress              ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypeurl                       ns_available_ios(10_0);
uikit_extern uitextcontenttype const uitextcontenttypecreditcardnumber          ns_available_ios(10_0);

8.usernotifications(用户通知)

ios 10 中将通知相关的 api 都统一了,在此基础上很多用户定义的通知,并且可以捕捉到各个通知状态的回调.以前通知的概念是:大家想接受的提前做好准备,然后一下全两分发,没收到也不管了,也不关心发送者,现在的用户通知做成了类似于网络请求,先发一个request得到response的流程,还封装了error,可以在各个状态的方法中做一些额外的操作,并且能获得一些字段,比如发送者之类的.这个功能的头文件是:#import <usernotifications/usernotifications.h>
主要有以下文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import <usernotifications/nsstring+usernotifications.h>
#import <usernotifications/unerror.h>
#import <usernotifications/unnotification.h>
#import <usernotifications/unnotificationaction.h>
#import <usernotifications/unnotificationattachment.h>
#import <usernotifications/unnotificationcategory.h>
#import <usernotifications/unnotificationcontent.h>
#import <usernotifications/unnotificationrequest.h>
#import <usernotifications/unnotificationresponse.h>
#import <usernotifications/unnotificationsettings.h>
#import <usernotifications/unnotificationsound.h>
#import <usernotifications/unnotificationtrigger.h>
#import <usernotifications/unusernotificationcenter.h>
#import <usernotifications/unnotificationserviceextension.h>

9.uicollectionviewcell的的优化

在ios 10 之前,uicollectionview上面如果有大量cell,当用户活动很快的时候,整个uicollectionview的卡顿会很明显,为什么会造成这样的问题,这里涉及到了ios 系统的重用机制,当cell准备加载进屏幕的时候,整个cell都已经加载完成,等待在屏幕外面了,也就是整整一行cell都已经加载完毕,这就是造成卡顿的主要原因,专业术语叫做:掉帧.
要想让用户感觉不到卡顿,我们的app必须帧率达到60帧/秒,也就是说每帧16毫秒要刷新一次.

ios 10 之前uicollectionviewcell的生命周期是这样的:
1.用户滑动屏幕,屏幕外有一个cell准备加载进来,把cell从reusr队列拿出来,然后调用prepareforreuse方法,在这个方法里面,可以重置cell的状态,加载新的数据;
2.继续滑动,就会调用cellforitematindexpath方法,在这个方法里面给cell赋值模型,然后返回给系统;
3.当cell马上进去屏幕的时候,就会调用willdisplaycell方法,在这个方法里面我们还可以修改cell,为进入屏幕做最后的准备工作;
4.执行完willdisplaycell方法后,cell就进去屏幕了.当cell完全离开屏幕以后,会调用didenddisplayingcell方法.
ios 10 uicollectionviewcell的生命周期是这样的:
1.用户滑动屏幕,屏幕外有一个cell准备加载进来,把cell从reusr队列拿出来,然后调用prepareforreuse方法,在这里当cell还没有进去屏幕的时候,就已经提前调用这个方法了,对比之前的区别是之前是cell的上边缘马上进去屏幕的时候就会调用该方法,而ios 10 提前到cell还在屏幕外面的时候就调用;
2.在cellforitematindexpath中创建cell,填充数据,刷新状态等操作,相比于之前也提前了;
3.用户继续滑动的话,当cell马上就需要显示的时候我们再调用willdisplaycell方法,原则就是:何时需要显示,何时再去调用willdisplaycell方法;
4.当cell完全离开屏幕以后,会调用didenddisplayingcell方法,跟之前一样,cell会进入重用队列.
在ios 10 之前,cell只能从重用队列里面取出,再走一遍生命周期,并调用cellforitematindexpath创建或者生成一个cell.
在ios 10 中,系统会cell保存一段时间,也就是说当用户把cell滑出屏幕以后,如果又滑动回来,cell不用再走一遍生命周期了,只需要调用willdisplaycell方法就可以重新出现在屏幕中了.
ios 10 中,系统是一个一个加载cell的,二以前是一行一行加载的,这样就可以提升很多性能;
ios 10 新增加的pre-fetching预加载
这个是为了降低uicollectionviewcell在加载的时候所花费的时间,在 ios 10 中,除了数据源协议和代理协议外,新增加了一个uicollectionviewdatasourceprefetching协议,这个协议里面定义了两个方法:

?
1
2
- (void)collectionview:(uicollectionview *)collectionview prefetchitemsatindexpaths:(nsarray<nsindexpath *> *)indexpaths ns_available_ios(10_0);
- (void)collectionview:(uicollectionview *)collectionview cancelprefetchingforitemsatindexpaths:(nsarray<nsindexpath *> *)indexpaths ns_available_ios(10_0);

在colletionview prefetchitemsat indexpaths这个方法是异步预加载数据的,当中的indexpaths数组是有序的,就是item接收数据的顺序;
collectionview cancelprefetcingforitemsat indexpaths这个方法是可选的,可以用来处理在滑动中取消或者降低提前加载数据的优先级.
注意:这个协议并不能代替之前读取数据的方法,仅仅是辅助加载数据.
pre-fetching预加载对uitableviewcell同样适用.

10. uirefreshcontrol的使用

在ios 10 中, uirefreshcontrol可以直接在uicollectionview和uitableview中使用,并且脱离了uitableviewcontroller.现在refreshcontrol是uiscrollview的一个属性.
使用方法:

?
1
2
3
uirefreshcontrol *refreshcontrol = [[uirefreshcontrol alloc] init];
 [refreshcontrol addtarget:self action:@selector(loaddata) forcontrolevents:uicontroleventvaluechanged];
 collectionview.refreshcontrol = refreshcontrol;

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

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

延伸 · 阅读

精彩推荐
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

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

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

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

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

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

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

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

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

    daisy6092021-05-17
  • IOSiOS通过逆向理解Block的内存模型

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

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

    Swiftyper12832021-03-03
  • IOS解析iOS开发中的FirstResponder第一响应对象

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

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

    一片枫叶4662020-12-25
  • IOSiOS布局渲染之UIView方法的调用时机详解

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

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

    windtersharp7642021-05-04
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

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

    SimpleWorld11022021-01-28
  • IOSIOS开发之字典转字符串的实例详解

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

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

    苦练内功5832021-04-01