I have a protocol called NakedNavigationBar
.
I also have an extension that extends all UIViewController
s that conform to NakedNavigationBar
.
The problem is that in the extension I want to add default behaviour so that when the UIViewController
initialises, we use method swizzling on the UIViewController
.
Here is my protocol and extension:
import UIKit
protocol NakedNavigationBar
{
}
extension NakedNavigationBar where Self: UIViewController
{
public override class func initialize()
{
struct Static
{
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token)
{
let originalSelector = #selector(viewWillAppear(_:))
let swizzledSelector = #selector(nakedNavigationBar_viewWillAppear(_:))
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod))
if didAddMethod
{
class_replaceMethod(self,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod))
}
else
{
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
// MARK: - Swizzling Methods
func nakedNavigationBar_viewWillAppear(animated: Bool)
{
self.nakedNavigationBar_viewWillAppear(animated)
print("VWA Swizzling...")
// Hide the navigation bar
_setNavigationBarVisible(isVisible: false)
}
// MARK: -
private func _setNavigationBarVisible(isVisible isVisible: Bool)
{
// (Changes background and shadow image)
}
}
The errors I get when building are:
Essentially telling me that I cannot extend the protocol because it doesn’t have the UIViewController
methods. But as I understand it, the where Self: UIViewController
should make it so that this only works on a UIViewController
, extending the view controller only when it conforms to NakedNavigationBar
.
Originally the extension was extension UIViewController: NakedNavigationBar
but this makes all of my UIViewController
s instantly conform to NakedNavigationBar
rather than only the ones I choose.