I have a type that takes one generic parameter that is required to inherit from UIView
:
class Handler<View: UIView> {
...
}
Now, I want write a UIView extension
to provide a property that returns Handler
and uses Self
as the generic parameter, so that in subclasses of UIView
I'd always get the handler of type Handler<UIViewSubclass>
:
extension UIView {
var handler: Handler<Self>? { return nil }
}
However this does not compile:
Covariant 'Self' can only appear at the top level of property type
I have also tried to define a protocol HandlerProvider
first:
public protocol HandlerProvider {
associatedtype View: UIView
var handler: Handler<View>? { get }
}
(so far so good) and then extend UIView
with that protocol:
extension UIView: HandlerProvider {
public typealias View = Self
public var handler: Handler<View>? { return nil }
}
But that does not compile either:
Covariant 'Self' can only appear as the type of a property, subscript or method result; did you mean 'UIView'?
Is there a way in Swift to use Self
as a generic parameter for properties in extension?
Here is possible approach (to think with generics in a bit different direction).
Tested with Xcode 11.4 / swift 5.2
// base handling protocol
protocol Handling {
associatedtype V: UIView
var view: V { get }
init(_ view: V)
func handle()
}
// extension for base class, will be called by default for any
// UIView instance that does not have explicit extension
extension Handling where V: UIView {
func handle() {
print(">> base: \(self.view)")
}
}
// extension for specific view (any more you wish)
extension Handling where V: UIImageView {
func handle() {
print(">> image: \(self.view)")
}
}
// concrete implementer
class Handler<V: UIView>: Handling {
let view: V
required init(_ view: V) {
self.view = view
}
}
// testing function
func fooBar() {
// handlers created in place of handling where type of
// handling view is know, so corresponding handle function
// is used
Handler(UIView()).handle()
Handler(UIImageView()).handle()
}
Output:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.