iOS 13 启动黑屏的解决
更新Xcode之后,新项目需求,新建项目发现多了如图1所示两个新的文件SceneDelegate.h
和SceneDelegate.m
运行之后发现黑屏
,无论是真机还是模拟器都不行,换到iOS12的手机上则可以正常运行。
查看官方文档,SceneDelegate
是为了优化启动和实现iPad多任务处理功能(在ipad上同时打开多个窗口)做出的改动,将原本在AppDelegate
里的生命周期相关方法和window
分离出来。
iOS13以前
:AppDelegate管理App的生命周期和UI生命周期;iOS13以后
:AppDelegate管理App的生命周期和新增的UISceneSession生命周期,新增SceneDelegate
文件来管理UI生命周期和window
;
关于解决有两种情况:
- 不开发iPadOS多窗口App
1)将新增的SceneDelegate文件
删除
2)删除info.plist
文件中Application Scene Manifest
选项,如下图所示
3)在AppDelegate
中新增window属性
,在didFinishLaunchingWithOptions
方法中跟往常一样进行相应根控制设置及处理,并删除新增的UISceneSession
两个方法
(因为在iOS13以前的系统中,没有SceneDelegate文件,所以还是需要在AppDelegate方法中进行根控制的设置)
4)在SceneDelegate
中willConnectToSession
方法里进行根控制设置的时候也要添加相应的版本控制,需要注意的是,此处初始化window的时候需要用WindowScene进行初始化
,否则黑屏加载不出视图。
其他适配问题:
- 使用presentViewController推出页面,不会全屏,如图
原因:在iOS13之前,VC的
modalPresentationStyle
属性默认值为UIModalPresentationFullScreen
,而在iOS13中
改为了UIModalPresentationAutomatic
解决:设置vc.modalPresentationStyle = UIModalPresentationFullScreen;
- 私有KVC使用崩溃
运行之前项目突然崩溃,定位到UITextField 的Placeholder文字颜色设置
[self.phoneTextField setValue:[UIColor colorWithHexString:@"#888888"] forKeyPath:@"_placeholderLabel.textColor"];
[self.passwordTextField setValue:[UIColor colorWithHexString:@"#888888"] forKeyPath:@"_placeholderLabel.textColor"];
[self.registeTextField setValue:[UIColor colorWithHexString:@"#888888"] forKeyPath:@"_placeholderLabel.textColor"];
有两种解决方案:
//方法1:去掉下划线访问placeholderLabel
[self.phoneTextField setValue:[UIColor blueColor] forKeyPath:@"placeholderLabel.textColor"];
[self.phoneTextField setValue:[UIFont systemFontOfSize:20] forKeyPath:@"placeholderLabel.font"];
//方法2:改为修改并赋值属性字符串
NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString:@"请输入手机号" attributes:@{NSForegroundColorAttributeName : [UIColor redColor], NSFontAttributeName : [UIFont systemFontOfSize:14.0f]}];
self.phoneTextField.attributedPlaceholder = attributeStr;
- 隐藏tabbar上方黑色横线
由于之前的[UIImage new]
方法已经不奏效,且在iOS13
之后引入了UITabBarAppearance
,所以需要修改为
//去除顶部横线
if (@available(iOS 13.0, *)) {
UITabBarAppearance * tabbarAppearance = self.standardAppearance;
tabbarAppearance.shadowImage = [UIImage imageWithColor:[UIColor clearColor]];
tabbarAppearance.backgroundImage = [UIImage imageWithColor:[UIColor clearColor]];
self.standardAppearance = tabbarAppearance;
} else {
[self setBackgroundImage:[UIImage imageWithColor:[UIColor clearColor]]];
[self setShadowImage:[UIImage imageWithColor:[UIColor clearColor]]];
}
其中[UIImage imageWithColor:[UIColor clearColor]
是自定义UIImage分类方法 – 根据颜色生成图片方法,self为继承于UITabBar的自定义tab,如果引入相应不同项目的时候需要自己做相应改动。附上根据颜色生成图片的方法:
#import "UIImage+LSImageWithColor.h"
@implementation UIImage (LSImageWithColor)
+ (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@end
- UIWebView彻底弃用
iOS13
上,苹果在UIWebView的使用上明确标注了仅支持iOS2~iOS12
的系统,项目中有用到UIWebView
的需要全部替换成WKWebView
,如果需要适配 iOS 7 的可以通过openURL
的方式在 Safari 打开。如果没有修改,提交审核将会不通过!
- 三方SDK更新
各SDK(友盟、微信等)都根据iOS13进行了更新,有用到的需要去更新最新的SDK。
- 暗黑适配
1、图片适配
如果项目中有需要适配暗黑模式的图片,可以在Assets.xcassets中设置,具体需要什么样式自己根据项目情况设置
2、UIColor适配
iOS13之后UIColor增加了两个初始化方法来动态创建UIColor:
//类方法
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchOS);
//实例方法
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
当
系统切换模式
的时候,会自动触发这两个方法
来动态修改控件颜色,所以可以根据需要使用这两种方法来进行颜色设置,一般写在基类或者UIColor分类中
。
//UIColor分类中增加方法
+ (UIColor *)colorWithLightColor:(UIColor *)color withDarkColor:(UIColor *)darkColor{
if (@available(iOS 13.0, *)) {
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return darkColor;
}
return color;
}];
return dyColor;
}
return color;
}
//调用
self.view.backgroundColor = [UIColor colorWithLightColor:[UIColor whiteColor] withDarkColor:[UIColor blackColor]];
iOS13之后系统也提供了一些动态的颜色,如果直接设置提供的那些动态颜色,则不需要使用上面的方法,照常直接设置即可,系统会自动更改颜色,如:labelColor,systemBrownColor等。
- CGColor适配
CGColor在iOS13之后依然只能表示一种颜色,所以在切换模式后直接返回当前页面时,设置的CGColor并不会动态改变,此时需要调用监听模式切换的方法:
在用到CGColor的VC中重写-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
方法,将layer颜色设置重新写一遍
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
[super traitCollectionDidChange:previousTraitCollection];
self.logoutBtn.layer.borderColor = [UIColor colorWithHexString:@"#d6d7dc" withDarkHexString:@"#000000"].CGColor;
}
注:这个方法是重写一遍layer颜色设置,而不是只在该方法中设置颜色,因为该方法是在切换模式的时候触发,如果没有切换模式,也没有在其他地方设置颜色,那么你将得不到颜色。
- 设置单个VC的模式
if (@available(iOS 13.0, *)) {
[self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark];
} else {
}
- 关于LaunchImage
wwdc2019中说在
2020年4月
之后,所有支持iOS13
的App必须提供LaunchScreen.storyboard
,否则无法提交到 App Store。
设置步骤:
1)将启动图拖入Assets.xcassets
中
2)在LaunchScreen.storyboard
中拖入ImageView,设置全屏约束,设置图片,完成
注意:
1)如果运行没有出现启动图,是因为缓存问题,删除App重新运行,再不行,重启模拟器即可
2)真机使用Xcode安装了app,设置启动页之后上传AppStore审核通过,在AppStore下载app之前最好先卸载掉原先的,否则会出现启动页虽然能成功显示,但是在显示之前还有一小段时间显示白屏。