美文网首页
Xcode11 iOS13适配

Xcode11 iOS13适配

作者: 三岁就很乖 | 来源:发表于2019-12-14 20:50 被阅读0次

    1、问题一:报错 Multiple methods named 'numberOfItemsInSection:' found with mismatched result, parameter type or attributes

    这个问题是由于二维数组取值时,编译器不知道是什么对象,调用对象的方法会报错,在Xcode之前的版本没有问题,解决方法是,告诉编译器是什么类型,我的是UICollectionView类型,如下:

    解决前:

    NSInteger numberOfBeforeSection = [_update[@"oldModel"] numberOfItemsInSection:updateItem.indexPathBeforeUpdate.section];
    
    

    解决后:

     NSInteger numberOfBeforeSection = [(UICollectionView *)_update[@"oldModel"] numberOfItemsInSection:updateItem.indexPathBeforeUpdate.section];
    
    

    https://blog.csdn.net/bitcser/article/details/100113549

    2、获取当前控制器
    我在适配iOS 13之前获取当前控制器的方法是这样的

    UIViewController *result = nil;
            UIWindow * window = [[UIApplication sharedApplication].delegate window];
            //app默认windowLevel是UIWindowLevelNormal,如果不是,找到UIWindowLevelNormal的
            if (window.windowLevel != UIWindowLevelNormal) {
                NSArray *windows = [[UIApplication sharedApplication] windows];
    
                for(UIWindow * tmpWin in windows) {
    
                    if (tmpWin.windowLevel == UIWindowLevelNormal) {
                        window = tmpWin; break;
                    }
                }
            }
            id nextResponder = nil;
            UIViewController *appRootVC = window.rootViewController;
            // 如果是present上来的appRootVC.presentedViewController 不为nil
            if (appRootVC.presentedViewController) {
                //多层present
                while (appRootVC.presentedViewController) {
    
                    appRootVC = appRootVC.presentedViewController;
                    if (appRootVC) {
                        nextResponder = appRootVC;
                    }
                    else {
                        break;
                    }
                }
                // nextResponder = appRootVC.presentedViewController;
            }
            else {
                // 如果当前UIViewController顶层不是UIView,那就需要循环获取到该UIViewController对应的UIView,
                // 才能跳出循环›
                int i= 0;
                UIView *frontView = [[window subviews] objectAtIndex:i];
                nextResponder = [frontView nextResponder];
    
                while (![nextResponder isKindOfClass:[UIViewController class]]) {
    
                    i++; frontView = [[window subviews]objectAtIndex:i];
                    nextResponder = [frontView nextResponder];
                }
            } if ([nextResponder isKindOfClass:[UITabBarController class]]){
                UITabBarController * tabbar = (UITabBarController *)nextResponder;
                UINavigationController * nav = (UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex];
                // UINavigationController * nav = tabbar.selectedViewController ; 上下两种写法都行
                result = nav.childViewControllers.lastObject;
            }
            else if ([nextResponder isKindOfClass:[UINavigationController class]]){
    
                UIViewController * nav = (UIViewController *)nextResponder;
                result = nav.childViewControllers.lastObject;
            }
            else {
                result = nextResponder;
            }
            return result;
    

    打断点发现

    断点插图
    keywindownextResponder居然在iOS 13 中居然也变成了UIWindow
    所以我们可以通过绕过nextResponder来获取当前控制器:
    -(UIViewController *)currentViewController{
        UIWindow *window = [UIApplication sharedApplication].delegate.window;
        NSLog(@"window level: %.0f", window.windowLevel);
        if (window.windowLevel != UIWindowLevelNormal) {
            NSArray *windows = [[UIApplication sharedApplication] windows];
            for (UIWindow * tmpWin in windows) {
                if (tmpWin.windowLevel == UIWindowLevelNormal) {
                    window = tmpWin;
                    break;
                }
            }
        }
        
        //从根控制器开始查找
        UIViewController *rootVC = window.rootViewController;
        UIViewController *activityVC = nil;
        
        while (true) {
            if ([rootVC isKindOfClass:[UINavigationController class]]) {
                activityVC = [(UINavigationController *)rootVC visibleViewController];
            } else if ([rootVC isKindOfClass:[UITabBarController class]]) {
                activityVC = [(UITabBarController *)rootVC selectedViewController];
            } else if (rootVC.presentedViewController) {
                activityVC = rootVC.presentedViewController;
            }else {
                break;
            }
            
            rootVC = activityVC;
        }
        
        return activityVC;
    }
    

    来源:https://www.jianshu.com/p/520b25e783b9

    https://blog.csdn.net/qq_23091121/article/details/101023714

    3、TextField 修改属性 利用keypath

    /    iOS13 适配
     [self setValue:ba_placeholderFont forKeyPath:@"_placeholderLabel.font"];
    
     NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:self.placeholder attributes:@{NSFontAttributeName : ba_placeholderFont}];
    self.attributedPlaceholder = placeholderString;
    

    http://www.cocoachina.com/articles/83448
    4、重写的TextField setValue forKeyPath

    - (void)setBa_placeholderFont:(UIFont *)ba_placeholderFont
    {
        BAKit_Objc_setObj(@selector(ba_placeholderFont), ba_placeholderFont);
    //    iOS13 适配
    //    [self setValue:ba_placeholderFont forKeyPath:@"_placeholderLabel.font"];
        if (self.placeholder != nil) {
            NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:self.placeholder attributes:@{NSFontAttributeName : ba_placeholderFont}];
            self.attributedPlaceholder = placeholderString;
        }
    
    }
    
    
    - (void)setBa_placeholderColor:(UIColor *)ba_placeholderColor
    {
    //    BAKit_Objc_setObj(@selector(ba_placeholderColor), ba_placeholderColor);
    //    [self setValue:ba_placeholderColor forKeyPath:@"_placeholderLabel.textColor"];
        if (self.placeholder!=nil) {
            NSMutableAttributedString *placehoder = [[NSMutableAttributedString alloc]initWithString:self.placeholder];
            [placehoder addAttribute:NSForegroundColorAttributeName value:ba_placeholderColor range:NSMakeRange(0, self.placeholder.length)];
            self.attributedPlaceholder = placehoder;
        }
        
    }
    
    

    为什么做了一个判断,就是因为自己在运行时崩溃,因为有的TextFiled没有内容,就会造成NSMutableAttributedString里有nil
    异常现象:

    Terminating app due to uncaught exception 'NSInvalidArgumentException', 
    reason: 'NSConcreteMutableAttributedString initWithString:: nil value'
    

    预防方案:

    在构造NSMutableAttributedString或者NSAttributedString需要留意,设置的属性的值是否有可能存在nil的情况。这个很容易被人忽视,值得注意。

    https://blog.csdn.net/fhsahfihf/article/details/102592861

    相关文章

      网友评论

          本文标题:Xcode11 iOS13适配

          本文链接:https://www.haomeiwen.com/subject/mashnctx.html