天天看點

iOS 13 Xcode11 适配

1.

a.解決友盟 LSDefaults 崩潰

添加擴充類冷處理
           
+ (void)load{
    
    SEL originalSelector = @selector(doesNotRecognizeSelector:);
    SEL swizzledSelector = @selector(sw_doesNotRecognizeSelector:);
    
    Method originalMethod = class_getClassMethod(self, originalSelector);
    Method swizzledMethod = class_getClassMethod(self, swizzledSelector);
    
    if(class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))){
        class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    }else{
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

+ (void)sw_doesNotRecognizeSelector:(SEL)aSelector{
    //處理 _LSDefaults 崩潰問題
    if([[self description] isEqualToString:@"_LSDefaults"] && (aSelector == @selector(sharedInstance))){
        //冷處理...
        return;
    }
    [self sw_doesNotRecognizeSelector:aSelector];
}
           

b.其他 問題可以直接更新友盟即可

2.UIViewController 模态VC 卡片恢複成全屏 (同上擴充類)

+(void)load
{
    Method present = class_getInstanceMethod(self, @selector(presentViewController:animated:completion:));
    Method swizzNewPresent = class_getInstanceMethod(self, @selector(DJPresentViewController:Animated:completion:));
    method_exchangeImplementations(present, swizzNewPresent);
}
-(void)DJPresentViewController:(UIViewController *)viewcontroller Animated:(BOOL)animated completion:(void (^)(void))completion{
    if (@available(iOS 13.0, *)) {
        viewcontroller.modalPresentationStyle = UIModalPresentationFullScreen;
        [self DJPresentViewController:viewcontroller Animated:animated completion:completion];
    }else{
        [self DJPresentViewController:viewcontroller Animated:animated completion:completion];
    }
}
           

3.QMUIkit 内部報錯

a.建議pod 導入 更新repo
b.重新pod install 新版本4.0.0版本及以上都可以
c.本地有QMUIConfigurationTemplate檔案報錯 直接github上下載下傳下來直接替換
           

4.微信 WXApi 方法報錯 直接更新SDK 并更換函數方法

5.

a、UITextField 通過KVC方式修改空白提示語顔色 崩潰

[UITextField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor”];
           

解決

attributedPlaceholder
_textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"姓名" attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14],NSForegroundColorAttributeName:[UIColor redColor]}];
           

b、leftView、rightView 設定出錯

imageView 在 textfield.leftView 中寬高被 sizeToFit 了,imageView 中設定的寬高無效了。

(例如:rightView的子視圖限制布局, 會導緻rightView覆寫整個UITextField)

UIImageView *imageIcon = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 34, 30)];
imageIcon.image = [UIImage imageNamed:@"search_icon"];
imageIcon.contentMode = UIViewContentModeCenter;
 // Confuse in  iOS13  先添加一層view 再添加上去
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 50)];
leftView.backgroundColor = UIColor.clearColor;
[leftView addSubview:imageIcon];
UITextField *txtSearch = [[UITextField alloc] init];
txtSearch.leftView = leftView;
txtSearch.leftViewMode = UITextFieldViewModeAlways;
           

c、UISearchBar searchTextField 可以直接使用不用再次擷取

5、YYTextView && YYLabel 适配 完美解決的前提是 UIColor 必須正确适配

(copy 原文位址)

YYLabel 适配 YYLabel.m 添加如下代碼

#pragma mark - DarkMode Adapater

#ifdef __IPHONE_13_0
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
    [super traitCollectionDidChange:previousTraitCollection];
    
    if (@available(iOS 13.0, *)) {
        if([UITraitCollection.currentTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){
            [self.layer setNeedsDisplay];
        }
    } else {
        // Fallback on earlier versions
    }
}
#endif
           
YYTextView 适配 YYTextView.m 添加如下代碼
#pragma mark - Dark mode Adapter

#ifdef __IPHONE_13_0
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
    [super traitCollectionDidChange:previousTraitCollection];
    
    if (@available(iOS 13.0, *)) {
        if([UITraitCollection.currentTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){
            [self _commitUpdate];
        }
    } else {
        // Fallback on earlier versions
    }
}
#endif
           
額外要做的事情 NSAttributedString+YYText.m 去除部分CGColor 調用
- (void)setColor:(UIColor *)color {
    [self setColor:color range:NSMakeRange(0, self.length)];
}

- (void)setStrokeColor:(UIColor *)strokeColor {
    [self setStrokeColor:strokeColor range:NSMakeRange(0, self.length)];
}

- (void)setStrikethroughColor:(UIColor *)strikethroughColor {
    [self setStrikethroughColor:strikethroughColor range:NSMakeRange(0, self.length)];
}

- (void)setUnderlineColor:(UIColor *)underlineColor {
    [self setUnderlineColor:underlineColor range:NSMakeRange(0, self.length)];
}
           

6、iOS13 TabBarItem setTitleTextAttributes 設定無效

[tabBarItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                        RGB(146, 146, 146), NSForegroundColorAttributeName,
                                        [UIFont boldSystemFontOfSize:10.0f], NSFontAttributeName,
                                        nil] forState:UIControlStateNormal];
           

此方法設定顔色無效 更改為:

[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:RGB(252,50,79)} forState:UIControlStateSelected];
           

或者是

UITabBarAppearance *tabBarAppearance = [[UITabBarAppearance alloc] init];
        tabBarAppearance.stackedLayoutAppearance.selected.titleTextAttributes = @{NSForegroundColorAttributeName:RGB(252,50,79)};
        [[UITabBar appearance] setStandardAppearance:tabBarAppearance];
           

7、AppDelegate 不能再使用window 添加控制器

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中建立根控制器,會崩潰報錯:如下圖
    iOS 13 Xcode11 适配
  • Appdelegate找不到設定window的方法。

Xcode自動新增了一個SceneDelegate檔案,查找了一下官方文檔WWDC2019:Optimizing App Launch

iOS13之前,Appdelegate的職責全權處理App生命周期和UI生命周期;

iOS13之後,Appdelegate的職責是:

1、處理 App 生命周期

2、新的 Scene Session 生命周期

那UI的生命周期呢?交給新增的Scene Delegate處理

用圖表示就是:

iOS13之前:

iOS 13 Xcode11 适配

這種模式完全沒問題,因為隻有一個程序,隻有一個與這個程序對應的使用者界面

但是iOS13之後,Appdelegate不在負責UI生命周期,所有UI生命周期交給SceneDelegate處理:

iOS 13 Xcode11 适配
iOS 13 Xcode11 适配

是以初始化window方法需要改變:

現在不再Appdelegate的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 進行初始化,轉交給SceneDelegate的 willConnectToSession: 方法進行根控制器設定:

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

    UIWindowScene *windowScene = (UIWindowScene *)scene;
    self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
    self.window.frame = windowScene.coordinateSpace.bounds;
    self.window.rootViewController = [UITabBarController new];
    [self.window makeKeyAndVisible];
}