In Objective-C, it\'s possible to write something like that:
@property(retain) UIView *myView;
But how can
One and probably a bit ugly one of the ways to do that, is to create a wrapper protocol for UIView
:
protocol UIViewRef {
var instance: UIView { get }
}
Now it is possible to create a protocol which implements Protocol1
, Protocol2
and UIViewRef
, which is going to be used to get the UIView
itself:
protocol MyUIViewProtocol: UIViewRef, Protocol1, Protocol2 { }
And last step will be implementing UIViewRef protocols for your UIView
s, which, in you case, as I understand, already implement Protocol1
and Protocol2
:
// SomeOfMyViews already implements Protocol1 and Protocol2
extension SomeOfMyUIViews: MyUIViewProtocol {
var instance: UIView { return self }
}
As the result we have MyUIViewProtocol
, implementers of which hold a reference to a UIView
and each of them implement
Protocol1
and Protocol2
. One caveat though - to get the UIView
itself, we need to ask it's reference from instance
property. For example
// Lets say we're somewhere in a UIViewController
var views: [SomeOfMyUIView] = // Get list of my views
views.forEach { self.view.addSubview($0.instance) }
You can do this with a generic class using a where clause:
A where clause enables you to require that an associated type conforms to a certain protocol, and/or that certain type parameters and associated types be the same.
To use it, make the class your property is defined in a generic class with a type constraint to check if the type parameter for your property matches your desired base class and protocols.
For your specific example, it could look something like this:
class MyViewController<T where T: UIView, T: Protocol1, T: Protocol2>: UIViewController {
var myView: T
// ...
}
In Swift 4 it's finally possible. You can declare variable of some class conforming to protocol at the same time, like this:
class ClassA {
var someVar: String?
}
protocol ProtocolA {}
class ClassB {
var someOptional: (ClassA & ProtocolA)? // here is optional value
var some: ClassA & ProtocolA // here is non-optional value; need to provide init though :)
}