iOS13 适配

一、模态弹窗样式适配

/*
 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 system-provided subclasses may resolve UIModalPresentationAutomatic to other concrete presentation styles. Participation in the resolution of UIModalPresentationAutomatic is reserved for system-provided view controllers.
 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));

添加下面等类别即可统一修改:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIViewController (MXRModalPresentationStyle)
#ifdef __IPHONE_13_0
@property (nonatomic, assign) BOOL mxr_didSetModalPresentationStyle API_AVAILABLE(ios(13.0));
#endif

@end

NS_ASSUME_NONNULL_END
#import "UIViewController+MXRModalPresentationStyle.h"
#import <objc/runtime.h>

@implementation UIViewController (MXRModalPresentationStyle)

#ifdef __IPHONE_13_0

+ (void)load {
    if (@available(iOS 13.0, *)) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self mxr_swizzlingInstanceMethodWithClass:self.class
                                                 originSel:@selector(setModalPresentationStyle:)
                                              swizzlingSel:@selector(mxr_setModalPresentationStyle:)];
            [self mxr_swizzlingInstanceMethodWithClass:self.class
                                             originSel:@selector(presentViewController:animated:completion:)
                                          swizzlingSel:@selector(mxr_presentViewController:animated:completion:)];
        });
    }
}

static char MXRDidSetModalPresentationStyle;

- (void)setMxr_didSetModalPresentationStyle:(BOOL)mxr_didSetModalPresentationStyle {
    objc_setAssociatedObject(self, &MXRDidSetModalPresentationStyle, @(mxr_didSetModalPresentationStyle), OBJC_ASSOCIATION_ASSIGN);
}

- (BOOL)mxr_didSetModalPresentationStyle {
    id obj = objc_getAssociatedObject(self, &MXRDidSetModalPresentationStyle);
    if (obj) {
        return [obj boolValue];
    } else {
        return NO; // default value.
    }
}

- (void)mxr_setModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
    if (@available(iOS 13.0, *)) {
        self.mxr_didSetModalPresentationStyle = YES;
    }
    [self mxr_setModalPresentationStyle:modalPresentationStyle];
}

- (void)mxr_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    if (@available(iOS 13.0, *)) {
        if (!viewControllerToPresent.mxr_didSetModalPresentationStyle &&
            viewControllerToPresent.modalPresentationStyle == UIModalPresentationPageSheet) {
            viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
        }
    }
    [self mxr_presentViewController:viewControllerToPresent animated:flag completion:completion];
}

#pragma mark - Method Swizzling

+ (void)mxr_swizzlingInstanceMethodWithClass:(Class)cls originSel:(SEL)originSel swizzlingSel:(SEL)swizzlingSel {
    Method originMethod = class_getInstanceMethod(cls, originSel);
    Method swizzlingMethod = class_getInstanceMethod(cls, swizzlingSel);
    BOOL didAddMethod = class_addMethod(cls,
                                        originSel,
                                        method_getImplementation(swizzlingMethod),
                                        method_getTypeEncoding(swizzlingMethod));
    if (didAddMethod) {
        class_replaceMethod(cls,
                            swizzlingSel,
                            method_getImplementation(originMethod),
                            method_getTypeEncoding(originMethod));
    } else {
        method_exchangeImplementations(originMethod, swizzlingMethod);
    }
}
#endif

@end

二、暗黑模式

全局关闭暗黑模式
在Info.plist添加:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

或者

//强制关闭暗黑模式
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
    if(@available(iOS 13.0,*)){
        self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
    }
#endif

单个界面不遵循暗黑模式

在iOS13,为UIViewController和UIView扩展了一个新的API

@property(nonatomic) UIUserInterfaceStyle overrideUserInterfaceStyle;

将 overrideUserInterfaceStyle 设置为对应的模式,则强制限制该元素与其子元素以设置的模式进行展示,不跟随系统模式改变进行改变
设置 ViewController 的该属性, 将会影响视图控制器的视图和子视图控制器采用该样式
设置 View 的该属性, 将会影响视图及其所有子视图采用该样式
设置 Window 的该属性, 将会影响窗口中的所有内容都采用样式,包括根视图控制器和在该窗口中显示内容的所有演示控制器(UIPresentationController)

开启暗黑模式

+ (void)adaptDarkMode:(UIView *)view lightColor:(UIColor *)lightColor darkColor:(UIColor *)darkColor {
#ifdef __IPHONE_13_0
    if (@available(iOS 13.0, *)) {
        view.backgroundColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
            if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
                return darkColor;
            } else {
                return lightColor;
            }
        }];
    } else {
        view.backgroundColor = lightColor;
    }
#endif
}

模拟器调试
运行项目
点击Xcode底部调试栏中Environment Overrides
开启Interface Style,就可以切换了。

三、废弃MPMoviePlayerViewController

使用AVPlayerViewController 来替换MPMoviePlayerViewController控件

四、Sign In with Apple

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.
如果你的应用支持使用第三方登录,那么就必须加上苹果新推出的登录方式:Introducing Sign In with Apple。

五、私有方法 KVC 不允许使用

在 iOS 13 中不再允许使用 valueForKey、setValue:forKey: 等方法获取或设置私有属性,虽然编译可以通过,但是在运行时会直接崩溃,并提示一下崩溃信息

// 使用的私有方法
[_textField setValue:[UIColor redColor] forKeyPath:@“_placeholderLabel.textColor"];
// 崩溃提示信息
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug' 
// 替换的方案
_textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"输入"attributes:@{NSForegroundColorAttributeName: [UIColor redColor]}]; 

六、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 进行审批。

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