美文网首页
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

相关文章

  • iOS之iOS13适配总结

    前言 随便iOS开发开始更新变成Xcode11,适配iOS13变成了现在的当务之急。 新特性适配 一、新添加的Da...

  • CocoPods更换Ruby源及升级版本

    升级xcode11,项目适配iOS13,MJExtension报错,github上提示需要更新最新版本,使用终端 ...

  • xcode11创建新项目

    1,如果项目不需要适配iOS13以下的机型。xcode11之后,入口放在了SceneDelegate里面。直接使用...

  • xcode11遇到的坑

    苹果出了iOS13,为了适配升级了xcode11,但是升级成功后模拟器运行就报错: Library not fou...

  • Xcode11探索之旅

    在更新到Xcode11、iOS13之后,对原有项目进行适配各种操作。最近需求一个全新的APP,才发现Xcode11...

  • iOS13 快速适配方案汇总

    iOS13后推出暗黑模式,以及一些细节调整,如果不进行适配,用xcode11打包后,app显示会存在显示异常。本文...

  • ios13适配

    iOS13适配 1.私有KVC 在Xcode10上编译不会有问题,但是在Xcode11上编译的会崩溃。并且- (v...

  • iOS13 适配问题 看这一篇就够了

    技术参考: apple login IOS13适配-详细 iOS 13 适配(持续更新中) iOS13适配 掘金 ...

  • iOS 13适配

    技术参考: apple login IOS13适配-详细 iOS 13 适配(持续更新中) iOS13适配 掘金 ...

  • iOS13 适配

    因为2020.4起,所有app必须使用xcode11打包,所以近期处理了一下iOS13的适配工作。这里做一下记录,...

网友评论

      本文标题:Xcode11 iOS13适配

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