Just tried that, with struct AppModel --> class AppModel
:
Details
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, tiny primes world!")
ApplicationsListView (dataProvider: TinyPrimesStore ())
}
.padding()
}
}
protocol NamedModel : Identifiable, Equatable, Hashable {
var name: String { get }
}
extension NamedModel {
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.id == rhs.id &&
lhs.name == rhs.name
}
}
class AppModel: NamedModel {
var name: String = "<NotSet>"
}
extension AppModel: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
protocol ListViewDataProvider {
associatedtype Item: NamedModel
var items: [Item] { get set }
}
#if false
struct ApplicationsListView <Provider: ListViewDataProvider>: View {
var dataProvider: Provider
@State private var selectedAppID: UUID? = nil
var body: some View {
List (selection: $selectedAppID) {
ForEach (dataProvider.items, id: \.self) {u in
Text (u.name)
}
}
}
}
#else
struct ApplicationsListView<Provider: ListViewDataProvider>: View {
var dataProvider: Provider
@State private var selectedAppID: UUID? = nil
var body: some View {
Table (dataProvider.items, selection: $selectedAppID) {
TableColumn("Applications") { app in
Text(app.name)
}
}
}
}
#endif
class TinyPrimesStore: ListViewDataProvider {
var items: [SmallPrime] = [SmallPrime (2), SmallPrime (3), SmallPrime (5), SmallPrime (7)]
}
class SmallPrime: NamedModel {
let value: Int
let name : String
init (_ value: Int) {
let uv = [2, 3, 5, 7, 11, 13, 17, 19]
assert (uv.contains (value))
self.value = value
self.name = "Small prime: \(value)"
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
but now getting these errors:
No exact matches in call to initializer
- Found candidate with type 'UUID?' (SwiftUI.Table.init)
- Found candidate with type 'Binding<UUID?>' (SwiftUI.Table.init)
However, the errors go away if Table...TableColumn
construct is replaced with a List...ForEach
construct.
Edit (Use the correct type for the table row selection)
New Details
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, tiny primes world!")
ApplicationsListView (dataProvider: TinyPrimesStore ())
}
.padding()
}
}
#Preview {
ContentView()
}
protocol NamedModel : Identifiable, Equatable, Hashable {
var name: String { get }
}
extension NamedModel {
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.id == rhs.id &&
lhs.name == rhs.name
}
}
class AppModel: NamedModel {
var name: String = "<NotSet>"
}
extension AppModel: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
protocol ListViewDataProvider {
associatedtype Item: NamedModel
var items: [Item] { get set }
}
#if false
struct ApplicationsListView <Provider: ListViewDataProvider>: View {
var dataProvider: Provider
@State private var selectedAppID: Provider.Item.ID? = nil
var body: some View {
List (selection: $selectedAppID) {
ForEach (dataProvider.items, id: \.self) {u in
Text (u.name)
}
}
}
}
#else
struct ApplicationsListView<Provider: ListViewDataProvider>: View {
var dataProvider: Provider
@State private var selectedAppID: Provider.Item.ID? = nil
var body: some View {
Table (dataProvider.items, selection: $selectedAppID) {
TableColumn("Applications") { app in
Text(app.name)
}
}
}
}
#endif
class TinyPrimesStore: ListViewDataProvider {
var items: [SmallPrime] = [SmallPrime (2), SmallPrime (3), SmallPrime (5), SmallPrime (7)]
}
class SmallPrime: NamedModel {
let value: Int
let name : String
init (_ value: Int) {
let uv = [2, 3, 5, 7, 11, 13, 17, 19]
assert (uv.contains (value))
self.value = value
self.name = "Small prime: \(value)"
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}