適配ios13

更新Xcode之後,新項目需求,新建項目發現多瞭如圖1所示兩個新的文件SceneDelegate.h和SceneDelegate.m

運行之後發現黑屏,無論是真機還是模擬器都不行,換到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選項,如下圖所示

3)在AppDelegate中新增window屬性,在didFinishLaunchingWithOptions方法中跟往常一樣進行相應根控制設置及處理,並刪除新增的UISceneSession兩個方法

2、需要用到SceneDelegate進行開發或不想刪除該文件,且需要適配iOS13以前的版本。
解決核心:添加版本控制

1)AppDelegate中增加window屬性,在didFinishLaunchingWithOptions方法中用if (@available(iOS 13.0, *)){}進行版本控制,UISceneSession lifecycle裏的兩個方法也要添加版本控制,如下圖所示

(因爲在iOS13以前的系統中,沒有SceneDelegate文件,所以還是需要在AppDelegate方法中進行根控制的設置)
2)在SceneDelegate中willConnectToSession方法裏進行根控制設置的時候也要添加相應的版本控制,需要注意的是,此處初始化window的時候需要用WindowScene進行初始化,否則黑屏加載不出視圖。

其他適配問題:

1、使用presentViewController推出頁面,不會全屏,如圖

原因:在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 打開。如果沒有修改,提交審覈將會不通過!

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

6、暗黑適配
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等。

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之前最好先卸載掉原先的,否則會出現啓動頁雖然能成功顯示,但是在顯示之前還有一小段時間顯示白屏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章