程序员iOS DeveloperiOS

Method swizzling的坑点

2017-04-18  本文已影响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同样染色。
所以这种黑科技证明是不行的,只能另想办法。

上一篇下一篇

猜你喜欢

热点阅读