The Swift documentation says that adding initializers in an extension is possible, and the example in the document is about adding an initializer to a struct. Xcode doe
Well, if you really, really, really want to override an initialiser, there is a way.
Before you read further: never do this to change UIKit behaviour. Why? It could confuse the heck out of someone that can't figure out why a UIColor initialiser isn't doing what it normally does. Only do it to fix a UIKit bug, or add functionality, etc.
I have used the following to patch several iOS bugs.
extension UIColor {
private static var needsToOverrideInit = true
override open class func initialize() {
// Only run once - otherwise subclasses will call this too. Not obvious.
if needsToOverrideInit {
let defaultInit = class_getInstanceMethod(UIColor.self, #selector(UIColor.init(red:green:blue:alpha:)))
let ourInit = class_getInstanceMethod(UIViewController.self, #selector(UIColor.init(_red:_green:_blue:_alpha:)))
method_exchangeImplementations(defaultInit, ourInit)
needsToOverrideInit = false
}
}
convenience init(_red: CGFloat, _green: CGFloat, _blue: CGFloat, _alpha: CGFloat) {
// This is trippy. We swapped implementations... won't recurse.
self.init(red: _red, green: _green, blue: _blue, alpha: _alpha)
///////////////////////////
// Add custom logic here //
///////////////////////////
}
}
This is using the dynamic nature of Objective-C, called from Swift, to swap method definition pointers at runtime. If you don't know what this means, or implications of it, it is probably a good idea to read up on the topic before you use this code.