I'm trying to implement an extended function that should differ based on what type of class is using it. The objects need to be UIView (or subclass). It should always use function extended on the specified type, but if it doesn't conform to any of them they should use the UIView method instead (as a fallback).
Here is an example of what I'm trying to do:
protocol aProtocol {
typealias completionBlock = (_ finished:Bool)->()
func doSomething(completion: completionBlock)
}
extension UIView: aProtocol {
func doSomething(completion: (Bool) -> ()) {
print("Im an UIView")
}
}
extension aProtocol where Self: UILabel {
func doSomething(completion: (Bool) -> ()) {
print("im an UILabel")
}
}
extension aProtocol where Self: UIImageView {
func doSomething(completion: (Bool) -> ()) {
print("im an UIImageView")
}
}
Excecute:
UIView().doSomething { (foo) in } // Should print "Im an UIView"
UIButton().doSomething { (foo) in } // Should print "Im an UIView" (UIButton doesent have specified extended function so should fall back on the UIView function)
UILabel().doSomething { (foo) in } // Should print "im an UILabel"
UIImageView().doSomething { (foo) in } // Should print "im an UIImageView"
Which now prints:
Im an UIView
Im an UIView
Im an UIView
Im an UIView
This means that it always uses the UIView method, even though I want it to use it's own methods. My goal is so it prints:
Im an UIView
Im an UIView
im an UILabel
im an UIImageView
You can achieve that as below, You just need to expose aProtocol
to Objective-c
runtime for overriding
its methods in the extension
.
@objc protocol aProtocol {
typealias completionBlock = (_ finished:Bool)->()
func doSomething(completion: completionBlock)
}
extension UIView: aProtocol {
func doSomething(completion: (Bool) -> ()) {
print("Im an UIView")
}
}
extension UILabel {
override func doSomething(completion: (Bool) -> ()) {
// you can call super.doSomething(completion: completion)
print("im an UILabel")
}
}
extension UIImageView {
override func doSomething(completion: (Bool) -> ()) {
// you can call super.doSomething(completion: completion)
print("im an UIImageView")
}
}
Output:
Im an UIView
Im an UIView
im an UILabel
im an UIImageView