iOS 13 适配之: presentViewController 的坑

出现这个问题主要因为 iOS以后,模态出来的viewcontroller中 modalPresentationStyle的默认值改变了,

iOS 13之前,modalPresentationStyle值默认为:UIModalPresentationFullScreen

在iOS 13中,modalPresentationStyle默认值为:UIModalPresentationAutomatic

修改要模态viewcontroller的modalPresentationStyle为:UIModalPresentationFullScreen 就就可以填充全屏

后果:被怼了很惨,因为项目里有很多模态出来的VC是半透明,结果现在变成完全不透明,背景为黑色。



解决方法1:

挨个修改VC 的modalPresentationStyle;代码多不说,漏改是大事,万一以后还有很多是半透密的,每次都要写,烦…………

解决方法2:

利用OC的runtime机制,交换系统方法:presentViewController:animated:completion:

具体实现如下:

在基类的.m中 做交换

#import

+ (void)load{

    // 适配ios  13  这里做方法交换

    static dispatch_once_tonceToken;

    dispatch_once(&onceToken, ^{

        // 系统模态方法,  做方法交换

        Method systemPresent =class_getInstanceMethod(self,@selector(presentViewController:animated:completion:));

        Method custom_Method =class_getInstanceMethod(self,@selector(xbPresentViewController:animated:completion:));

        method_exchangeImplementations(systemPresent, custom_Method);

    });

}


- (void)xbPresentViewController:(UIViewController*)viewControllerToPresentanimated:(BOOL)flag completion:(void(^)(void))completion {

    //设置满屏,可以半透明

    if(@available(iOS13.0, *)) {

        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverFullScreen;

    }

    [self xbPresentViewController:viewControllerToPresentanimated:flagcompletion:completion];

}

后遗症:因为把显示效果修改为:UIModalPresentationOverFullScreen;半透明,全屏覆盖的问题都得到完美解决。但是会引发一个新的问题:前一个页面的viewWillAppear:、viewDidAppear:也无法触发。例如: A   Present  B, 有时因为业务逻辑需要,必须在viewWillAppear, viewDidAppear里写一些代码,当B 调用dismiss方法的时候, A的这个两个方法不会触发,因此会有一些安全隐患。因此如果要求B 调用dismiss方法,A要执行viewWillAppear:、viewDidAppear:这个两个方法,这个时候要把B的modalPresentationStyle设置为:UIModalPresentationFullScreen;

方法改进:

- (void)myPresentViewController:(UIViewController*)viewControllerToPresentanimated:(BOOL)flagcompletion:(void(^)(void))completion {

    //设置满屏,可以半透明

    if(@available(iOS13.0, *)) {

        if([viewControllerToPresent isKindOfClass:[YourViewController class]]) {

            viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;

        } else {

            viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverFullScreen;

        }

    }

    [self myPresentViewController:viewControllerToPresentanimated:flagcompletion:completion];

}


其他:如果要求 B既要半透明,dismiss时,A还要调用viewWillAppear:、viewDidAppear:。我的想法是在B 写一个block,在B调用dismiss之前,利用block回调A相关的业务逻辑代码。如果有其他更好的方法请告诉我。万分感谢!!

你可能感兴趣的:(iOS 13 适配之: presentViewController 的坑)