Warm tip: This article is reproduced from stackoverflow.com, please click
swiftui

Composability with types in SwiftUI

发布于 2020-03-27 10:21:37

The goal is to have a table where the rows are different types, and each is a 'component.' So imagine the LandmarkRow from the Apple Tutorial, but instead of Landmarks, we were also going to show Accommodations as well. I want to make each its own component, that part is easy.

The part that is more challenging is how I get the view from each, if they are in a collection. What would be ideal is if they both implement a protocol, and then I can have them in a collection of types that includes that protocol and then just call the commmon method, e.g. buildView. The problem is is that opaque types seems to break inheritance. If I make a build() -> some View method in the base, providing an implementation in the derived classes is not seen as an override. So I don't get the derived. Instead, for now, I am just doing if item is Landmark for each type in the body of the table view.

Just to be super clear, I don't want a switch or a block of if statements, this is OO 101: we should be able to derive a new type that implements the protocol then add that type into the collection that the table is composed of.

We did find that we could force cast the view to the protocol and then call the method, that works. Has the advantage of not having to edit a switch or if block each time a new view is added, but still unnecessary/incorrect.

Questioner
Rob
Viewed
62
Rob 2019-07-05 23:01

Turns out Apple does provide a solution to this, though not in the sample, but in the session 'SwiftUI on All Devices.' Around 26 minutes in they discuss providing 2 different LandmarkRow implementations, but they do not use inheritance. They use generics and a lambda. There is no code in the resources for this but you can see it all in the session.