Reputation: 403
Is there a way to be notified when for example every window/viewcontroller has called viewDidLoad
? Like a viewcontrollers tracker. I don't want to repeat code too much. Thanks
Upvotes: 0
Views: 147
Reputation: 1239
There is another method that doesn't require any overriding of all classes inside of your project to inherit from BaseViewController
. That's method swizzling.
Method swizzling is the process of changing the implementation of an existing selector at runtime. Basically, it is just changing the functionality of a method at runtime.
So, you can do the following:
extension UIViewController {
static let classInit: Void = {
let originalSelector = #selector(viewDidLoad)
let swizzledSelector = #selector(proj_viewDidLoad)
swizzling(UIViewController.self, originalSelector, swizzledSelector)
}()
// MARK: - Method Swizzling
@objc func proj_viewDidLoad() {
self.proj_viewDidLoad()
let viewControllerName = NSStringFromClass(type(of: self))
/// Whatever you want in here
print("viewDidLoad: \(viewControllerName)")
}
}
private let swizzling: (AnyClass, Selector, Selector) -> () = { forClass, originalSelector, swizzledSelector in
guard
let originalMethod = class_getInstanceMethod(forClass, originalSelector),
let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
After that, you need to activate it in AppDelegate
this way:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
UIViewController.classInit
}
/// ... the rest
}
That's it!
Upvotes: 3
Reputation: 1396
You may create a BaseViewController
and inherit from it every other view controller that you want to observe.
class BaseViewController:UIViewController{
func viewDidLoad(){
super.viewDidLoad()
print("inherit all viewControllers with this class")
print("perform your work you wanted to do")
}
}
class firsViewController: BaseViewController{
func viewDidLoad(){
super.viewDidLoad()
print("I will call baseViewController too")
}
}
class SecondViewController: BaseViewController{
func viewDidLoad(){
super.viewDidLoad()
print("I will call baseViewController too")
}
}
Upvotes: 3
Reputation: 594
You have several ways to do this:
You can create Global class for ex : you have your ViewController class with the code in and then you create subclasses of this instead of UIViewController as concept of inheritance mentioned in another answer.
Or you can also create extension , protocols and class with class methods and you can use that class shared instance to every where you want in view controller.
Upvotes: 1
Reputation: 1125
Create a base view controller, extend all your controllers with it instead of UIViewController like class MyViewController: BaseViewController {
, then you can do anything in the base's viewDidLoad
which will run for all controller's having them all do super.viewDidLoad
.
Upvotes: 2