iOS - 如何在可见(顶部)视图控制器更改时收到通知

时间:2018-01-12 19:48:20

标签: ios objective-c model-view-controller

我正在尝试构建推送模型,以检测iOS应用中的可见视图控制器更改。

我知道我可以监听所有willDidAppear方法或实现类似的委托方法。

例如:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

另外,我知道我可以听UINavigationControllerDidShowViewControllerNotification,但不是每个类都是UINavigationController的子类。所以这对我来说可能不起作用。

我想知道有没有更简单,更健壮的方法来实现目标? 谢谢!

1 个答案:

答案 0 :(得分:0)

你可以通过添加扩展到UIViewController和swizzle viewDidLoad方法用你自己的方法来做到这一点所以每次任何UIViewController推送或呈现你自己的viewDidLoad实现都会被调用,你可以做任何你想要的东西,你也可以调的任何方法不仅viewDidLoad 看看这个如何工作的例子

extension UIViewController {
// We cannot override load like we could in Objective-C, so override initialize instead
public override static func initialize() {

    // Make a static struct for our dispatch token so only one exists in memory
    struct Static {
        static var token: dispatch_once_t = 0
    }

    // Wrap this in a dispatch_once block so it is only run once
    dispatch_once(&Static.token) {
        // Get the original selectors and method implementations, and swap them with our new method
        let originalSelector = #selector(UIViewController.viewDidLoad)
        let swizzledSelector = #selector(UIViewController.myViewDidLoad)

        let originalMethod = class_getInstanceMethod(self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

        let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

        // class_addMethod can fail if used incorrectly or with invalid pointers, so check to make sure we were able to add the method to the lookup table successfully
        if didAddMethod {
            class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
}

// Our new viewDidLoad function
// In this example, we are just logging the name of the function, but this can be used to run any custom code
func myViewDidLoad() {
    // This is not recursive since we swapped the Selectors in initialize().
    // We cannot call super in an extension.
    self.myViewDidLoad()
    print("do what you want here") // logs myViewDidLoad()
}
}