iOS13和Xcode11踩坑
今年整体上问题不大,没有出现编译报错问题。
用 Xcode10 编译的 App 在 iOS 13 上使用甚至几乎完美
用 Xcode11 编译的 App 再在 iOS 13 上跑,就有些问题了
modal新样式
iOS 13 多了一个新的枚举类型 UIModalPresentationAutomatic
,且是modalPresentationStyle
的默认值。
UIModalPresentationAutomatic
实际是表现是在 =iOS 13的设备上被映射成UIModalPresentationPageSheet
。
我这边的设计师表示,新样式不错,可以不用改😆。
不过, PageSheet
与 FullScreen
对比 有个需要注意的地方,控制器的生命周期有点区别:
以 控制器A
、控制器B
举例:
控制器A
present控制器B
控制器A
不会调用viewWillDisappear
以及viewDidDisappear
控制器B
dismiss 时
控制器A
不会调用viewWillAppear
以及viewDidAppear
那么如果有些业务逻辑会在控制器A
的生命周期里做的话,就需要考虑其他方式实现,或者改回UIModalPresentationFullScreen
如果需要改成原本全屏的样式,可以处理Controller:
- 初始化时设置
modalPresentationStyle
值 - 跳转修改
modalPresentationStyle
值 - 覆盖
modalPresentationStyle
的get方法
看上面gif,用户是可以通过手势下拉关闭被present出来的控制器的,那如果我需要禁止他下来要怎么实现呢?
可以参考disabling_pulling_down_a_sheet的Demo
设置presentationController.delegate
代理对象,实现UIAdaptivePresentationControllerDelegate
协议方法
1 | @interface XXViewController () <UIAdaptivePresentationControllerDelegate> |
textfield.leftview
如下方式,直接给textfield.leftView
赋值一个UILabel
对象,他的宽高会被 sizeToFit
,而不是创建时的值。
1 | // left view label |
如所看到,实际leftview的width为59,height为19:
通过监听leftView
的frame
变化,发现是layoutSubview
之后变化的。
最终还是给UILabel多套了一个UIView来解决
1 | // label |
KVC访问私有属性Crash
打开有UISearchBar
的页面发现Crash了,看到控制台输出提示:
1 | // 获取_searchField |
看起来是禁止访问私有属性了。
用 Xcode 10 编译的 App 在 iOS 13 上能正常使用,那么就是 Xcode 11 做了限制访问私有属性的一些处理了。
偶然发现 iOS 13 中增加了UISearchTextField
类,且暴露了searchTextField
。
1 | // UISearchTextField.h |
但是仅在 iOS 13 以上系统支持,还是暂时用遍历view的方式去做了😂
navigationBar:shouldPopItem:
点击导航栏返回的时候Crash了,控制台输出提示:
1 | Теrmіnаtіng арр due to uncaught exception' NSInternalInconsistencyException' , |
因为我们工程里,基本上所有的Controller
是继承基类BaseViewController
并实现- (BOOL)naviBack:
方法,用于实现在用户点击返回和侧滑返回时,一些不能返回的特殊处理。
其根本原理是通过实现UINavgationBar
的代理方法- (BOOL)navigationBar:shouldPopItem:
来做的控制:
1 | - (BOOL)navigationBar:(UINavigationBar *)navigationBar |
但是我实现的时候有Return YES
啊!想了想,试着注释了[self popViewControllerAnimated:YES]
,发现没有崩溃了。
但是在iOS 12上,会发现控制器没有回到上一层,如图,只有navbar回到上一层了:
好吧,那只能判断一下版本解决这个问题了,修改方式:
1 | - (BOOL)navigationBar:(UINavigationBar *)navigationBar |
夜间模式
WWDC 19 直播的时候看到夜间模式,老实说挺开心的,直到我用 Xcode 11 开始做适配,妈耶!x N
注意:使用 Xcode 10 编译的 App 依然是日间模式,不会产生效果!!!
初步扫了一下出现的问题如下图,大致情况是:没有设置背景色的系统控件会被设置成黑色,部分控件是tintColor没设置的话也会被改。
由于Assets里的Color配置是iOS 12
以上才能使用的,所以如果没有做全局主题色设计且需要支持iOS 12以下设备,改起来会比较恶心。
对此现象,找设计师沟通。设计师表示,暂时没有精力做夜间模式规划。
设计师问:能否强制只日间模式?
答:能。配置方式有两种,单页面配置
和 全局配置
。
- 单页配置
将需要配置的UIViewControler
对象的overrideUserInterfaceStyle
属性设置成UIUserInterfaceStyleLight
或者UIUserInterfaceStyleDark
以强制是某个页面显示为浅/深色模式
- 全局配置
在工程的Info.plist
的中,增加/修改UIUserInterfaceStyle
为UIUserInterfaceStyleLight
或UIUserInterfaceStyleDark
禁用方法
textField 更改holder颜色崩溃
1 | [textField setValue:HexColor(0x999999) forKeyPath:@"_placeholderLabel.textColor"]; |
解决方式
1 | NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"请输入占位文字" attributes:@{NSForegroundColorAttributeName:HexColor(0x999999), NSFontAttributeName:textField.font}]; |