我正在尝试构建推送模型,以检测iOS应用中的可见视图控制器更改。
我知道我可以监听所有willDidAppear
方法或实现类似的委托方法。
例如:
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
另外,我知道我可以听UINavigationControllerDidShowViewControllerNotification
,但不是每个类都是UINavigationController
的子类。所以这对我来说可能不起作用。
我想知道有没有更简单,更健壮的方法来实现目标? 谢谢!
答案 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()
}
}