Search code examples
iosswiftuiviewcontrollerviewdidappearswizzle

How to exclude UIViewControllers other than views from Swizzle Method?


I am trying to override viewDidAppear() methods of my custom ViewControllers and i found a solution using swizzle method. It works but when keyboard is visible, my method also gathers Keyboard UIViewControllers like;

    UIInputWindowController
    UICompatibilityInputViewController
    UISystemKeyboardDockController
    UIInputWindowController
    UICompatibilityInputViewController
    UICompatibilityInputViewController
    UISystemInputAssistantViewController
    UIPredictionViewController
    UISystemKeyboardDockController

I wonder how can i exclude all UIViewControllers other than my custom ViewControllers? I can exclude those UIViewControllers that i encounter so far but i think there will be UIViewControllers other than those in the future. I think i need a generic solution.

My code is as below:

extension UIViewController {
    @objc func viewDidApperOverride(_ animated: Bool) {
        self.viewDidApperOverride(animated)
        print(NSStringFromClass(type(of: self)))  
    }

    static func swizzle() {
        if self != UIViewController.self {
            return
        }
        
        let originalSelector = #selector(UIViewController.viewDidAppear(_:))
        let swizzledSelector = #selector(UIViewController.viewDidApperOverride(_:))
        guard let originalMethod = class_getInstanceMethod(self, originalSelector),
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) else { return }
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
}

Solution

  • You could just ignore every ViewController who's class name starts with "UI" or "_". You can get a VC's class name string with type(of: self).description().