iOS 13 适配

推荐文章


iOS Swift 自定义导航栏 FLNavigationBar 解决所有问题

新特性适配


1. 第三方登录

Sign In with Apple will be available for beta testing this summer. It will be required as an option for users in apps that support third-party sign-in when it is commercially available later this year. [原文]

如果 APP 支持三方登陆(Facbook、Google、微信、QQ、支付宝等),就必须支持苹果登录,且要放前边.

Sign in with Apple 设计规范

2. 黑暗模式

通过UITraitCollection.currentTraitCollection.userInterfaceStyle获取当前模式。

iOS 13提供了内置的动态Color,会根据当前userInterfaceStyle自动显示不同的颜色。

UIColor systemFillColor
UIColor secondarySystemFillColor
UIColor tertiarySystemFillColor
UIColor quaternarySystemFillColor
...

// 更多的时候需要自定义动态颜色:
(UIColor )colorWithDynamicProvider:(UIColor (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
(UIColor )initWithDynamicProvider:(UIColor (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
//在回调中根据不同的userInterfaceStyle返回不同的颜色。

Web 同样需要适配黑暗模式
Web Content适配
APP 适配教程
Adopting iOS Dark Mode
iOS13 Dark Mode 适配
WWDC2019-214-iOS 13 适配 dark mode
WWDC 设计分会:iOS 13 设计新特性(1)
WWDC 设计分会:iOS 13 设计新特性(2)

Api 变化


1. KVC 限制

iOS13 以后已经不能肆无忌惮的通过 KVC 来修改一些没有暴露出来的属性了

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to xxx's _xxx ivar is prohibited. This is an application bug'

// UITextField 的 _placeholderLabel
[textField setValue:[UIColor xxx] forKeyPath:@"_placeholderLabel.textColor"];

// UISearchBar 的 _searchField
[searchBar valueForKey:@"_searchField"];

2. DeviceToken有变化


[deviceToken description] 获取到的格式发生变化

// objc
NSString *dt = [deviceToken description];
dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];
// swift
let dt = deviceToken.description.replacingOccurrences(of:"<", with:"").replacingOccurrences(of:">", with:"").replacingOccurrences(of:" ", with:"")

解决方案

// objc
NSMutableString *dt= [NSMutableString string];
const char *bytes = deviceToken.bytes;
NSInteger count = deviceToken.length;
for (int i = 0; i < count; i++) {
    [dt appendFormat:@"%02x", bytes[i]&0x000000FF];
}
// swift
var dt: String = ""
let bytes = [UInt8](deviceToken)
for item in bytes {
     dt += String(format:"%02x", item&0x000000FF)
}

3. CNCopyCurrentNetworkInfo 变化


An app that fails to meet any of the above requirements receives the following return value:

  • An app linked against iOS 12 or earlier receives a dictionary with pseudo-values. In this case, the SSID is Wi-Fi (or WLAN in the China region), and the BSSID is 00:00:00:00:00:00.
  • An app linked against iOS 13 or later receives NULL.

iOS13 以后只有开启了 Access WiFi Information capability,才能获取到 SSID 和 BSSID
参考:CNCopyCurrentNetworkInfo

4. 蓝牙权限说明

// 在iOS 13之前,想获取手机连接的蓝牙设备信息,可以直接使用此方法, 并不需要声明权限
[CBCentralManager retrieveConnectedPeripheralsWithServices:]

iOS 13之后,必须在Info.plist文件中增加NSBluetoothAlwaysUsageDescription说明,否则crash。

视图适配


  • 之前标记为 API_DEPRECATED 部分类被移除

1. UISearchDisplayController

在 iOS 8 之前,我们在 UITableView 上添加搜索框需要使用 UISearchBar + UISearchDisplayController 的组合方式,而在 iOS 8 之后,苹果就已经推出了 UISearchController 来代替这个组合方式。在 iOS 13 中,如果还继续使用 UISearchDisplayController 会直接导致崩溃,崩溃信息如下:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'UISearchDisplayController is no longer supported when linking against this version of iOS. Please migrate your application to UISearchController.' 

另外说一下,在 iOS 13 中终于可以获取直接获取搜索的文本框:

_searchBar.searchTextField.text = @"search";

2. MPMoviePlayerController 被弃用

在 iOS 9 之前播放视频可以使用 MediaPlayer.framework 中的MPMoviePlayerController类来完成,它支持本地视频和网络视频播放。但是在 iOS 9 开始被弃用,如果在 iOS 13 中继续使用的话会直接抛出异常:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'

解决方案是使用 AVFoundation 里的 AVPlayer

3. LaunchImage 被弃用

iOS 8 之前我们是在LaunchImage 来设置启动图,但是随着苹果设备尺寸越来越多,我们需要在对应的 aseets 里面放入所有尺寸的启动图,这是非常繁琐的一个步骤。因此在 iOS 8 苹果引入了 LaunchScreen.storyboard,支持界面布局用的 AutoLayout + SizeClass ,可以很方便适配各种屏幕。

需要注意的是,苹果在 Modernizing Your UI for iOS 13 section 中提到,从2020年4月开始,所有支持 iOS 13 的 App 必须提供 LaunchScreen.storyboard,否则将无法提交到 App Store 进行审批。

4. 模态弹出默认交互改变


/*
 Defines the presentation style that will be used for this view controller when it is presented modally. Set this property on the view controller to be presented, not the presenter.
 If this property has been set to UIModalPresentationAutomatic, reading it will always return a concrete presentation style. By default UIViewController resolves UIModalPresentationAutomatic to UIModalPresentationPageSheet, but other system-provided view controllers may resolve UIModalPresentationAutomatic to other concrete presentation styles.
 Defaults to UIModalPresentationAutomatic on iOS starting in iOS 13.0, and UIModalPresentationFullScreen on previous versions. Defaults to UIModalPresentationFullScreen on all other platforms.
 */
@property(nonatomic,assign) UIModalPresentationStyle modalPresentationStyle API_AVAILABLE(ios(3.2));

iOS 13 的 presentViewController 默认有视差效果,模态出来的界面现在默认都下滑返回。 一些页面必须要点确认才能消失的,需要适配。如果项目中页面高度全部是屏幕尺寸,那么多出来的导航高度会出现问题。

// Swift
self.modalPresentationStyle = .fullScreen

// Objective-C
self.modalPresentationStyle = UIModalPresentationFullScreen;


这样带来了新的交互方式,下拉就可以 dismiss 控制器,实测这是个很爽的功能,体验大幅度提升,但是对我们开发者来说呢,带来了一些坑,下面让我们来看看吧。

首先 UIModalPresentationStyle 增加了一个 automatic 属性,在 iOS 13 下默认就是这个属性。系统会根据推出的控制器来选择是 pageSheet 还是 fullScreen,比如当我们用 UIImagePickerController 推出相机是 fullScreen,我们自己写的控制器是 pageSheet。如果我们只想推出 fullScreen 的控制器也很简单,present 之前设置 vc.modalPresentationStyle = .fullScreen 就好了。

接下来说一下 pageSheet 的坑是什么,我们先来看下 fullScreen 的调用顺序。

再来看下 pageSheet 的调用顺序

当A控制器 present B控制器,A控制器的 viewWillDisappearviewDidDisappear 不会调用,当B控制器 dismiss,A控制器的 viewWillAppearviewDidAppear 也不会调用。也就是说如果你有一些逻辑是放在这4个方法中的,要么把业务逻辑换个地方,要么设置 vc.modalPresentationStyle = .fullScreen

另外,UIViewController 增加一个了属性 isModalInPresentation,默认为 false,当该属性为 false 时,用户下拉可以 dismiss 控制器,为 true 时,下拉不可以 dismiss控制器。该属性可以配合有编辑功能的控制器使用,让我们来看下官方的 Demo

image

<figcaption></figcaption>

我们可以看到,未编辑内容时下拉可以 dismiss,编辑了内容后下拉不可以dismiss,同时弹出了一个 alert 提示用户要不要保存编辑过的内容。详细的代码大家可以去 Demo 里看,这里就简单说一下。

首先判断用户是否输入,有输入将 isModalInPresentation 改为 true。然后实现 UIAdaptivePresentationControllerDelegate 代理的 presentationControllerDidAttemptToDismiss: 方法。这个方法会在 isModalInPresentation = true,且用户尝试下拉 dismiss 控制器时调用。最后在这个方法里弹出 alert 提示用户是否保存编辑过的内容即可。

5. UISegmentedControl 默认样式改变

默认样式变为白底黑字,如果设置修改过颜色的话,页面需要修改原本设置选中颜色的 tintColor 已经失效,新增了 selectedSegmentTintColor 属性用以修改选中的颜色。

6. UITabbar 层次发生改变,无法通过设置 shadowImage去掉上面的线

7. App启动过程中,部分View可能无法实时获取到frame


可能是为了优化启动速度,App 启动过程中,部分View可能无法实时获取到正确的frame

// 只有等执行完 UIViewController 的 viewDidAppear 方法以后,才能获取到正确的值,在viewDidLoad等地方 frame Size 为 0,例如:
 [[UIApplication sharedApplication] statusBarFrame];

8. UISearchBar 黑线处理导致崩溃

之前为了处理搜索框的黑线问题,通常会遍历 searchBar 的 subViews,找到并删除 UISearchBarBackground,在 iOS13 中这么做会导致 UI 渲染失败,然后直接崩溃,崩溃信息如下:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Missing or detached view for search bar layout'

解决办法是设置 UISearchBarBackground 的 layer.contents 为 nil:

for (UIView *view in _searchBar.subviews.lastObject.subviews) {
    if ([view isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
        // [view removeFromSuperview];
        view.layer.contents = nil;
        break;
    }
}

9. UIActivityIndicatorView

之前的 UIActivityIndicatorView 有三种 style 分别为 whiteLarge, whitegray,现在全部废弃。
增加两种 style 分别为 mediumlarge,指示器颜色用 color 属性修改。

10. UINavigationBar

修改 layoutMargins 属性崩溃

// MARK: layoutMargins 设置
- (void)barGainASystemView {
    if (@available(iOS 11.0, *)) {
        if (!_systemNavigationBarContentView) {
            for (UIView *subView in self.subviews) {
                if ([NSStringFromClass([subView class]) isEqualToString:@"_UINavigationBarContentView"]) {
                    _systemNavigationBarContentView = subView;
                }
            }
        }
        if (_systemNavigationBarContentView) {
//            _systemNavigationBarContentView.layoutMargins = UIEdgeInsetsZero;
        }
    }
}
·参考文献

本文结合以下文档内容和个人遇到的问题,对常见适配问题进行总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 在简书偶尔会被锁定,本文在掘金也同步更新。 iOS 13 支持适配的机型 iPhone 11、iPhone 11 ...
    _森宇_阅读 9,511评论 2 37
  • iOS 13 如期而至,适配工作可以开展起来啦。在适配 iOS 13 过程中,遇到了如下一些问题。 1. UITe...
    前行哲阅读 20,197评论 48 136
  • iOS13 beta版本已经发布,手痒的升级Xcode和iOS,同时也发现了一些问题,这里更新下。。。 KVC i...
    张叔叔阅读 24,726评论 10 15
  • 私有KVC 与系统版本无关,与Xcode版本有关,Xcode11编译会奔溃。 其中UITextField [tex...
    Kity_Pei阅读 15,714评论 12 13
  • 前言 苹果爸爸又出新品,想必各位大佬,都是紧跟其步伐,在此总结下目前iOS 13 遇到的奔溃,以及Dark Mod...
    天下林子阅读 1,734评论 1 12