美文网首页
iOS 13 适配之: presentViewControlle

iOS 13 适配之: presentViewControlle

作者: 小白e7899 | 来源:发表于2019-10-22 17:18 被阅读0次

    出现这个问题主要因为 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 <objc/runtime.h>

    + (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 适配之: presentViewControlle

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