Hi guys. I have found myself fighting the type system, which probably means I am doing (or thinking) something totally wrong, and I need your programming eagle's eye to spot it.
In my app I have a settings view (controller) which displays views of different settings panes (which are ViewControllers) - one at a time, adding their view as its subview.
Now, here's my issue. Each settings pane is a class defined as follows:
protocol SettingsPane {
var componentTitle: String { get }
func saveState()
}
class SettingsPaneVC: UIViewController, SettingsPane {
...
}
Sometimes I need its UIViewController
and other times the SettingsComponent
part of the interface, and so I have found myself in a situation where I need to settle for one of these, and then force-downcast whenever I need the other one. E. g.:
var components: [SettingsPane] = [
SomeSettingsPane(),
AnotherSettingsPane(),
etc...
]
for component in components {
(component as! UIViewController).view.frame = ....
}
// but...
...text = self.components.first!.componentTitle
What I am looking for is a solution which would allow me to get rid of downcasting. I have been trying to leverage the fact that anything conforming to SettingsComponent
should always be a subclass of UIViewController
, but I haven't come up with anything acceptable. So far, my attempts have resulted in such code:
protocol SettingsPane {
var componentTitle: String { get }
var view: UIView! { get set } //what I need from UIViewController
func saveState()
}
Is there a way of making the entire UIViewController
's interface available through SettingsPane
? Or am I destined to list in SettingsPane
specifically what I need?
If every SettingsPane
is going to be a subclass of UIViewController
, you could just create a SettingsViewController
subclass.
class SettingsViewController : UIViewController {
var componentTitle: String {
fatalError()
}
func saveState() {
fatalError()
}
}
I realize there are some problems with this:
UITableViewController
or UICollectionViewContorller
.
extension SettingsPane where Self : UIViewController {}
Is there a way of making the entire UIViewController's interface available through SettingsPane?
This is a subclass.
Or am I destined to list in SettingsPane specifically what I need?
Yes, which might actually be a good thing. You might want to hide all of the UIViewController
stuff away if you just need the UIView
. You didn't specify what else you needed so that might be a terrible idea.
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.