0

I want to swizzle viewDidLoad in a UIViewController extension but initialize() method which was overridden in swift3 and was working is not supported by swift4. Can anyone give me any solution to this? My code in swift3 was as below.

    extension UIViewController {

    open override class func initialize() {

        guard self === UIViewController.self else { return }
        swizzling(self)
    }

    // MARK: - Method Swizzling

    func nsh_viewDidLoad() {
        self.nsh_viewDidLoad()

        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
    }

and have a global method

private let swizzling: (UIViewController.Type) -> () = { viewController in

    let originalSelector = #selector(viewController.viewDidLoad)
    let swizzledSelector = #selector(viewController.nsh_viewDidLoad)

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

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

    if didAddMethod {
        class_replaceMethod(viewController, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
}
Jack
  • 13,571
  • 6
  • 76
  • 98
Soumen
  • 2,070
  • 21
  • 25
  • Could you please explain why would you want to swizzle in the first place? Usually it means you are doing something very wrong... – Sulthan Oct 17 '17 at 10:26
  • 2
    Do you understand that what you are trying to do is a very complicated way to do a very simple thing that can be achieved using one subclass? E.g. subclassing `UINavigationController` to hide all back button titles on its controller and then just use your subclass instead of `UINavigationController`? – Sulthan Oct 17 '17 at 10:41
  • I am trying to convert an existing project to swift 4 so if I subclass `UINavigationController`, I need to change in many classes in the project. But thank you for the suggestion this will be my alternate solution if swizzling doesn't work. – Soumen Oct 17 '17 at 10:46
  • If you want to do it fast, just call that `initialize` from your `AppDelegate`. – Sulthan Oct 17 '17 at 10:46
  • Possible duplicate of [Swift 3.1 deprecates initialize(). How can I achieve the same thing?](https://stackoverflow.com/questions/42824541/swift-3-1-deprecates-initialize-how-can-i-achieve-the-same-thing). – Martin R Oct 17 '17 at 10:49
  • @Sulthan Can you please explain how to call `initialize` from `AppDelegate` can solve the problem? – Soumen Oct 17 '17 at 10:50

1 Answers1

0

I added the below code in AppDelegate instead if swizzling

let barButtonItemAppearance = UIBarButtonItem.appearance()
        barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
        barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .highlighted)
Soumen
  • 2,070
  • 21
  • 25