I'm defining a protocol called PanelController
in which I'd like to store a PanelView
. PanelView
itself is a subclass of UIView
and defines the basic structure of panel. I have three different views that subclass PanelView
: LeftPanel
, MidPanel
, and RightPanel
. For each of those panels I'd like to define a xxxPanelController
(left, mid, right) that conforms to the PanelController
protocol.
The issue I'm running up against is in the protocol and xxxPanelController
protocol PanelController {
var panelView: PanelView { get set }
...
}
and
class LeftPanelController: UIViewController, PanelController {
var panelView = LeftPanelView()
...
}
where
class LeftPanelView: PanelView {
...
}
and (one last piece...)
class PanelView: UIView {
...
}
I get an error saying that: LeftPanelController does not conform to protocol PanelController
for an obvious reason: panelView
is of type LeftPanelView
not PanelView
. This seems really limited to me, though, because LeftPanelView
is a subclass of PanelView
so it should just work! But it doesn't!
Can someone explain to me why this is, and if anyone can come up with one, a possible workaround? Thanks!
A protocol can require any conforming type to provide an instance property or type property with a particular name and type. The protocol doesn't specify whether the property should be a stored property or a computed property—it only specifies the required property name and type.
You can have properties in a protocol, provided every class that conforms to your protocol have a corresponding @synthesize for that property, or provide a getter and setter. But with a class category you generally can't add instance variables to a class.
A protocol defines a blueprint of methods, properties, and other requirements. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. But there would be a time when you want to restrict protocols to be adopted by a specific class.
Protocols allow you to group similar methods, functions, and properties. Swift lets you specify these interface guarantees on class , struct , and enum types. Only class types can use base classes and inheritance from a protocol.
The problem is with the setter in the protocol.
Let's say you want to GET the panelView
from LeftPanelController
. That's fine, because LeftPanelView
can do everything PanelView
can do (and more).
If you want to SET the panelView
of LeftPanelController
though, you can give it any PanelView
. Because you're defining the panelView
variable as a LeftPanelView
, the setter could sometimes fail.
To fix this, you could do the following in LeftPanelController
:
var panelView: PanelView = LeftPanelView()
The implication of this is that you won't be able to access any methods or properties that are specific to LeftPanelView
without casting it first. If that's not an issue, then this should fix your problem!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With