Method swizzling的坑点

作者: 高浩浩浩浩浩浩 | 来源:发表于2017-04-18 10:09 被阅读172次

    iOS的ViewController默认backgroundColorclearColor,如果不设置背景颜色,会导致新界面的背景是透明色,还会导致跳转动画卡顿。
    但是每创建一个ViewController就要设置一次backgroundColor。那么有没有什么办法可以简化呢?
    最近在复习runtimeMethod swizzling的知识,于是决定用runtime的知识来处理下这个问题:

    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
        Class class = [self class];
        
        SEL originalSelector = @selector(viewDidLoad);
        SEL swizzledSelector = @selector(ghh_viewDidLoad);
        
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        });
    }
    
    - (void)ghh_viewDidLoad {
        self.view.backgroundColor = [UIColor lightGrayColor];
        [self ghh_viewDidLoad];
        NSLog(@"%@ method did changed!", self);
    }
    

    没一会儿就写完了,调试运行结果。没有问题!

    Screen Shot 2017-04-17 at 下午7.43.31.png

    但是在滑动返回的时候,整个界面变成灰色了!

    Screen Shot 2017-04-17 at 下午7.48.30.png

    同时控制台打印结果:

    2017-04-17 19:47:53.411627+0800 ThugLife[9251:4390465] <UINavigationController: 0x100816000> method did changed!
    2017-04-17 19:47:53.434202+0800 ThugLife[9251:4390465] <ViewController: 0x1004095c0> method did changed!
    2017-04-17 19:47:54.785103+0800 ThugLife[9251:4390465] <UINavigationController: 0x100810c00> method did changed!
    2017-04-17 19:47:54.788516+0800 ThugLife[9251:4390465] <GHHPhotoViewController: 0x10042e190> method did changed!
    2017-04-17 19:47:54.899452+0800 ThugLife[9251:4390465] <GHHGridViewController: 0x10043cd60> method did changed!
    2017-04-17 19:47:58.734195+0800 ThugLife[9251:4390465] <GHHPhotoEditingViewController: 0x100440a70> method did changed!
    2017-04-17 19:47:59.991616+0800 ThugLife[9251:4390465] <UIInputWindowController: 0x100906200> method did changed!

    打开UI调试,看页面层级关系图貌似也没问题:

    Paste_Image.png

    但是除了正常的UIWindow之外,还有一个UITextEffectsWindow,查看这个window,发现页面什么都没有。在此找到了罪魁祸首,就是这个东西挡在了UI前面导致显示失败

    Paste_Image.png

    原因

    iOS 8 inserts a new “UITextEffectsWindow” above your application’s main UIWindow that currently intercepts clicks when selecting items in the Reveal canvas. To work around this you can either Command-Click to select through the UITextEffectsWindow or double-click on your app’s UIWindow in Reveal’s outline view to focus on the application window.

    在Google了相关资料后发现,这是一个iOS8以后新加入的私有window,根据网上说法是用来控制键盘的专属window,后面查证,当vc存在于navigationVC下 此时不管是否弹出键盘 [UIApplication shareappliation] windows 都会包含UITextEffectsWindow
    所以当滑动popViewController的时候,这个window被加在UIWindow上,挡住了整个UI视图。

    而且这种方法还会对iOS8以后的UIAlertController同样染色。
    所以这种黑科技证明是不行的,只能另想办法。

    相关文章

      网友评论

        本文标题:Method swizzling的坑点

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