1. 获取状态栏
项目中有通过StatusBar来获取手机当前状态,但是在iOS 13中会崩溃,调试了一下发现是通过KVC获取UIApplication
的statusBar
属性造成的。iOS13新增加了UIStatusBarManager
相关的类,可以通过获取程序window进而获取到UIStatusBarManager。
然后通过Runtime获取到UIStatusBarManager
的属性列表及方法列表:
|
可以看到有几个与statusBar相关的属性和方法,最总尝试了很多次,只有通过createLocalStatusBar
可以获取到_UIStatusBarLocalView
|
然后通过KVC进而获取到UIStatusBar_Modern
|
最终拿到了statusBar,详细代码如下:
|
通过上述方法运行后获取statusBar再次出现崩溃,查看到相关信息如下:
|
猜想可能是调用createLocalStatusBar
方法时有UI的创建或者动画,而此时的调用可能是在子线程里操作的,所以增加了线程判断再去获取statusBar,最终解决问题:
|
以上方法调用了一些系统私有方法,还不晓得上线审核是否会被拒。
2. 暗黑模式适配
- 在Info.plist 文件中,添加
UIUserInterfaceStyle
key为User Interface Style
类型为String, - 将
UIUserInterfaceStyle
key 的值设置为Light
UIViewController与UIView 都新增了一个属性
overrideUserInterfaceStyle
将
overrideUserInterfaceStyle
设置为对应的模式,则强制限制该元素与其子元素以设置的模式进行展示,不跟随系统模式改变进行改变
- 设置 ViewController 的该属性,将会影响视图控制器的视图和子视图控制器采用该样式
- 设置 View 的该属性,将会影响视图及其所有子视图采用该样式
- 设置 Window 的该属性, 将会影响窗口中的所有内容都采用样式,包括根视图控制器和在该窗口中显示内容的所有演示控制器(UIPresentationController)
目前全局禁止了暗黑模式,部分页面还需要等UI设计下暗黑模式的效果。
- TODO
暗黑模式的适配可以参考这里
3. UITextField设置placeholder颜色
|
iOS 13中通过KVC设置占位文本颜色会崩溃,详细信息如下:
|
提示该方法已经被禁止使用,可以改成使用attributedPlaceholder
来设置:
|
上面的代码比较多,如果项目中使用KVC方式赋值颜色的地方比较多,修改后的代码会比较冗余。为此我为UITextField
写了一个分类,不用写其它多余代码,一行代码即可搞定,在老代码KVC赋值的地方相应替换为:
|
分类详细代码如下:
|
4. UITextField的leftView和内边距调整
之前项目通过设置leftView来达到设置UITextField内边距的效果,在iOS 13版本上失效,原因是在iOS 13中如果使用UIImageView来设置leftView,则必须为其设置一个有效的image,否则将无法按照意愿布局。
|
解决方案,改为UIView或者把UIImageVIew 包一层UIView再设置给leftView,且不要使用约束布局。
|
不过,以上方案设置UITextField的内边距有很大的局限性,例如我想使用图片来设置一个真正可见的leftView,并且还想调整内边距,显然这种方法无法满足需求,为此我为UITextField写了个分类,简单一行代码即可设置UITextField的文本和占位符的内边距:
|
5. 模态跳转ModalPresent
iOS 13系统下修改了模态跳转样式,苹果可能是想与push页面有侧滑手势一样,增加了下滑手势,个人感觉体验不错,交互样式也有提升,不用再自己手写转场动画了。当然如果想改成老样式,可以手动改成UIModalPresentationOverFullScreen
,不过个人推荐使用iOS 13新增加的枚举值UIModalPresentationAutomatic
,使用系统推荐的模态样式:
|
默认情况下不设置即是pageSheet样式,当然除 UISearchController
和 UIAlertController
因自身业务的特殊性不同外,其余的视图控制器均为此展示样式。
如果项目中禁止了全局暗黑模式,但还想使用pageSheet样式,还要记得配置下window的颜色,不然弹出后window背景色是白色看不出分层次效果:
|
6. 关于_LSDefaults崩溃问题
程序运行后可能会出现_LSDefaults崩溃:
|
可能是友盟SDK版本问题导致,升级后即可正常运行。
还有在网上看到的解决方案是通过拦截系统的doesNotRecognizeSelector:
方法,强行终止其抛出异常,具体实现可以参考这里。虽然理论上可以拦截或重载这个函数实现不抛出异常,但是苹果文档则建议是“一定不能让这个函数就这么结束掉,必须抛出异常”。