Reputation: 31
List
with selection
binding, a custom rowView
with two TextField
in it.struct DemoView: View {
@ObservedObject var model: DemoModel
var body: some View {
List(selection: self.$model.selectedRows) {
DisclosureGroup(isExpanded: self.$model.isExpanded, content: {
ForEach(self.model.models) { rowModel in
RowView(rowModel: rowModel)
.contentShape(Rectangle())
.swipeActions {
Button("Swipe") {
}
}
}
.onMove { fromIndices, toIndex in
self.model.models.move(fromOffsets: fromIndices, toOffset: toIndex)
}
}, label: {
HStack(alignment: .center) {
Text("Title")
Spacer()
Button("Add row", systemImage: "plus") {
let rowModel = RowModel()
self.model.models.append(rowModel)
}
}
})
}
}
}
class DemoModel: ObservableObject {
@Published var models: [RowModel]
@Published var isExpanded: Bool
@Published var selectedRows: Set<UUID>
init() {
let one = RowModel()
let two = RowModel()
self.models = [one, two]
self.isExpanded = true
self.selectedRows = Set()
}
}
enum CustomFocusState {
case textFieldOne, textFieldTwo
}
struct RowView: View {
@ObservedObject var rowModel: RowModel
@FocusState var focuseState: CustomFocusState?
var body: some View {
HStack {
TextField("Enter text", text: self.$rowModel.text)
.textFieldStyle(.roundedBorder)
.padding()
.focusable()
.focused($focuseState, equals: .textFieldOne)
.onTapGesture {
self.focuseState = .textFieldOne
print("tapped textFieldOne")
}
TextField("Enter text", text: self.$rowModel.text2)
.textFieldStyle(.roundedBorder)
.padding()
.focusable()
.focused($focuseState, equals: .textFieldTwo)
.onTapGesture {
self.focuseState = .textFieldTwo
print("tapped textFieldTwo")
}
}
}
}
class RowModel: ObservableObject, Identifiable {
@Published var text: String
@Published var text2: String
var id: UUID
init() {
self.text = ""
self.text2 = ""
self.id = UUID()
}
}
extension RowModel: Hashable {
static func == (lhs: RowModel, rhs: RowModel) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.id)
}
}
.onMove
modifier, the row selection and the TextField
focus seems to work but I'm not sure why?Upvotes: 3
Views: 157
Reputation: 30746
Change RowModel
to a struct. It doesn't make sense for classes to be identified by id, since they already are identified by their pointer, so change it to a struct. @Published
needs to be an array of model structs to work anyway.
Also, remove selection from the model store object. If you think about it you might want the model data to be presented in different ways all which might need their own selection so selection should be @State
instead.
Upvotes: 0