欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

适配ios13

程序员文章站 2024-03-24 13:20:58
...

更新Xcode之后,新项目需求,新建项目发现多了如图1所示两个新的文件SceneDelegate.h和SceneDelegate.m

适配ios13

运行之后发现黑屏,无论是真机还是模拟器都不行,换到iOS12的手机上则可以正常运行。
查看官方文档,SceneDelegate是为了优化启动和实现iPad多任务处理功能(在ipad上同时打开多个窗口)做出的改动,将原本在AppDelegate里的生命周期相关方法和window分离出来
iOS13以前:AppDelegate管理App的生命周期和UI生命周期;
iOS13以后:AppDelegate管理App的生命周期和新增的UISceneSession生命周期,新增SceneDelegate文件来管理UI生命周期和window;
关于解决有两种情况:
1、不开发iPadOS多窗口App
1)将新增的SceneDelegate文件删除
2)删除info.plist文件中Application Scene Manifest选项,如下图所示

适配ios13

3)在AppDelegate中新增window属性,在didFinishLaunchingWithOptions方法中跟往常一样进行相应根控制设置及处理,并删除新增的UISceneSession两个方法

适配ios13

2、需要用到SceneDelegate进行开发或不想删除该文件,且需要适配iOS13以前的版本。
解决核心:添加版本控制

1)AppDelegate中增加window属性,在didFinishLaunchingWithOptions方法中用if (@available(iOS 13.0, *)){}进行版本控制,UISceneSession lifecycle里的两个方法也要添加版本控制,如下图所示

适配ios13

(因为在iOS13以前的系统中,没有SceneDelegate文件,所以还是需要在AppDelegate方法中进行根控制的设置)
2)在SceneDelegate中willConnectToSession方法里进行根控制设置的时候也要添加相应的版本控制,需要注意的是,此处初始化window的时候需要用WindowScene进行初始化,否则黑屏加载不出视图。

适配ios13

其他适配问题:

1、使用presentViewController推出页面,不会全屏,如图

适配ios13

原因:在iOS13之前,VC的modalPresentationStyle属性默认值为UIModalPresentationFullScreen,而在iOS13中改为了UIModalPresentationAutomatic
解决:设置vc.modalPresentationStyle = UIModalPresentationFullScreen;
2、私有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;

3、隐藏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

4、UIWebView彻底弃用
iOS13上,苹果在UIWebView的使用上明确标注了仅支持iOS2~iOS12的系统,项目中有用到UIWebView的需要全部替换成WKWebView,如果需要适配 iOS 7 的可以通过 openURL 的方式在 Safari 打开。如果没有修改,提交审核将会不通过!

适配ios13

5、三方SDK更新
各SDK(友盟、微信等)都根据iOS13进行了更新,有用到的需要去更新最新的SDK。

6、暗黑适配
1、图片适配
如果项目中有需要适配暗黑模式的图片,可以在Assets.xcassets中设置,具体需要什么样式自己根据项目情况设置

适配ios13

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等。

3、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颜色设置,而不是只在该方法中设置颜色,因为该方法是在切换模式的时候触发,如果没有切换模式,也没有在其他地方设置颜色,那么你将得不到颜色。

4、设置单个VC的模式

if (@available(iOS 13.0, *)) {
        [self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark];
    } else {

    }

仅限于当前VC,推出或返回的VC依然是跟随系统模式。

7、关于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之前最好先卸载掉原先的,否则会出现启动页虽然能成功显示,但是在显示之前还有一小段时间显示白屏。

相关标签: UI相关