TableView mit selection zeigt Auswahl nicht

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • TableView mit selection zeigt Auswahl nicht

    ich bräuchte bitte mal wieder Hilfe vom Fachmann / -frau.

    Folgendes Problem:

    Habe analog zur Doku eine TableView mit selection erstellt. Zuerst habe ich eine Hauptview, in der ich eine SubView aufrufe. (Brauche ich irgendwie wegen des Filters).

    Quellcode

    1. struct UmsaetzeView: View {
    2. @Environment(\.dismiss) var dismiss
    3. @ObservedObject private var konto: Konten
    4. @State var selectedUmsaetze = Set<KontoUmsaetze.ID>()
    5. @State var selectedKlient: Klienten?
    6. @State private var rlFilter: Bool = false
    7. init(selectedKlient: Klienten, konto: Konten) {
    8. self.konto = konto
    9. _selectedKlient = State(initialValue: selectedKlient)
    10. }
    11. @State var filter: String = ""
    12. var body: some View {
    13. VStack(alignment: .leading) {
    14. [hier viel anderes Zeug, auch eine Suche mit $filter]
    15. UmsaetzeListView(
    16. konto: konto,
    17. klient: selectedKlient!,
    18. selectedUmsaetze: $selectedUmsaetze,
    19. filter: filter,
    20. rlZeitraum: rlFilter
    21. )
    22. }
    23. }
    24. }
    Alles anzeigen

    In der UmsaetzeListView ist meine Tabelle

    Quellcode

    1. struct UmsaetzeListView: View {
    2. @FetchRequest var transacts: FetchedResults<KontoUmsaetze>
    3. @ObservedObject private var konto: Konten
    4. @Binding var selectedUmsaetze: Set<KontoUmsaetze.ID>
    5. init(
    6. konto: Konten,
    7. klient: Klienten,
    8. selectedUmsaetze: Binding<Set<KontoUmsaetze.ID>>,
    9. filter: String,
    10. rlZeitraum: Bool = false
    11. ) {
    12. self.konto = konto
    13. _selectedUmsaetze = selectedUmsaetze
    14. var predicates = [NSPredicate]()
    15. if konto.iban != nil {
    16. predicates.append(NSPredicate(format: "iban = %@", (konto.iban)! as CVarArg))
    17. }
    18. var filterPred = [NSPredicate]()
    19. if filter != "" {
    20. filterPred.append(NSPredicate(format: "billingNo CONTAINS[cd] %@", filter))
    21. filterPred.append(NSPredicate(format: "recipient CONTAINS[cd] %@", filter))
    22. filterPred.append(NSPredicate(format: "verwendungszweck CONTAINS[cd] %@", filter))
    23. predicates.append(NSCompoundPredicate(type: .or, subpredicates: filterPred))
    24. }
    25. if rlZeitraum {
    26. let cal = Calendar.current
    27. var timePred = [NSPredicate]()
    28. let sdComp = cal.dateComponents([.year, .month, .day], from: (klient.rechnungslegungVon)!)
    29. let sd = cal.date(
    30. from: DateComponents(
    31. year: sdComp.year,
    32. month: sdComp.month,
    33. day: sdComp.day,
    34. hour: 0,
    35. minute: 0,
    36. second: 0
    37. )
    38. )
    39. let edComp = cal.dateComponents([.year, .month, .day], from: (klient.rechnungslegungBis)!)
    40. let ed = cal.date(
    41. from: DateComponents(
    42. year: edComp.year,
    43. month: edComp.month,
    44. day: edComp.day,
    45. hour: 23,
    46. minute: 59,
    47. second: 59
    48. )
    49. )
    50. timePred.append(NSPredicate(format: "valuta >= %@", sd! as CVarArg))
    51. timePred.append(NSPredicate(format: "valuta <= %@", ed! as CVarArg))
    52. predicates.append(NSCompoundPredicate(type: .and, subpredicates: timePred))
    53. }
    54. _transacts = FetchRequest<KontoUmsaetze>(
    55. sortDescriptors: [SortDescriptor(\KontoUmsaetze.valuta, order: .reverse), SortDescriptor(\KontoUmsaetze.counter, order: .forward)],
    56. predicate: NSCompoundPredicate(type: .and, subpredicates: predicates),
    57. animation: .default
    58. )
    59. }
    60. var body: some View {
    61. Table(transacts, selection: $selectedUmsaetze, sortOrder: $transacts.sortDescriptors) {
    62. TableColumn("date", value: \.valuta) { transact in
    63. Text(transact.valuta!, formatter: Formatters.dateFormatter)
    64. .bold()
    65. Spacer()
    66. }
    67. .width(70)
    68. TableColumn("Nr.", value: \.billingNo) { transact in
    69. Text(transact.billingNo ?? "")
    70. Spacer()
    71. }
    72. .width(75)
    73. TableColumn("Empf.", value: \.recipient) { transact in
    74. Text(transact.recipient ?? "")
    75. Spacer()
    76. }
    77. TableColumn("Verw.-Zw.", value: \.recipient) { transact in
    78. Text(transact.verwendungszweck ?? "")
    79. .lineLimit(4)
    80. .font(.caption)
    81. .help(transact.verwendungszweck ?? "")
    82. Spacer()
    83. }
    84. TableColumn("€", value: \.amount) { transact in
    85. Text(Formatters.currencyFormatter.string(from: transact.amount as NSNumber)!)
    86. .foregroundColor(transact.amount < 0.0 ? .red : .primary)
    87. .bold()
    88. Spacer()
    89. }
    90. .width(80)
    91. .alignment(.trailing)
    92. TableColumn("") { transact in
    93. Image(systemName: "circle.fill")
    94. .foregroundColor(
    95. .red
    96. )
    97. Spacer()
    98. }
    99. .width(20)
    100. }
    101. .font(.callout)
    102. Text("\(selectedUmsaetze.count)")
    103. }
    104. }
    Alles anzeigen
    Jetzt mein Problem: Programm wird gestartet und alles funktioniert auch soweit. Nur wenn ich in der obigen Tabelle eine Zeile auswähle, geht der Zähler unten um eines hoch, aber die Zeile ist nicht als ausgewählt sichtbar. Klicke ich dieselbe Zeile noch mal an, stürzt das Programm ab mit dem Hinweis, dass ein doppelter Eintrag im Set wäre.

    Auch wenn ich den Filter weg lasse und die Tabelle direkt in die Hauptview baue, dasselbe Problem.

    Bin gerade ziemlich ratlos, was die Ursache sein könnte und wäre für Hilfe dankbar.
  • Es scheint, dass das Problem in der Art und Weise liegt, wie die Zeilen in der Tabelle ausgewählt und im Set selectedUmsaetze gespeichert werden. Da du angibst, dass der Zähler unten um eins hochgeht, die Zeile aber nicht als ausgewählt sichtbar ist und ein erneutes Auswählen zum Absturz führt, könnte es an einer inkorrekten Implementierung des Selection-Bindings liegen.
    Um das Problem zu beheben, kannst du sicherstellen, dass die Zeilen korrekt ausgewählt und im Set gespeichert werden. Hier sind einige Schritte, die du überprüfen und anpassen kannst:
    1. Set im UmsaetzeView aktualisieren: Stelle sicher, dass das Set selectedUmsaetze im UmsaetzeView korrekt aktualisiert wird. Überprüfe, ob es Änderungen in der Auswahl gibt und ob diese an die UmsaetzeListView weitergeleitet werden.

    Quellcode

    1. UmsaetzeListView(
    2. konto: konto,
    3. klient: selectedKlient!,
    4. selectedUmsaetze: $selectedUmsaetze,
    5. filter: filter,
    6. rlZeitraum: rlFilter
    7. )



    2. Binding in UmsaetzeListView verwenden: Stelle sicher, dass das Binding für die ausgewählten Zeilen in der UmsaetzeListView korrekt verwendet wird. In der Table-Ansicht sollte das Binding wie folgt verwendet werden:


    Quellcode

    1. Table(transacts, selection: $selectedUmsaetze, sortOrder: $transacts.sortDescriptors) {
    2. // ... deine Spalten
    3. }


    3. Zweimal dasselbe Set vermeiden: Stelle sicher, dass du nicht versehentlich dasselbe Set in zwei verschiedenen Views verwendest oder es doppelt bindest, was zu Fehlern führen kann.
    4. Optionalen Set korrekt initialisieren: Falls das Set optional ist, stelle sicher, dass es richtig initialisiert wird, um null-Werte zu vermeiden.

    Quellcode

    1. @State var selectedUmsaetze: Set<KontoUmsaetze.ID> = []
    Wenn das Problem weiterhin besteht, könntest du auch versuchen, das Set durch ein Array zu ersetzen und überprüfen, ob das Verhalten weiterhin auftritt:

    Quellcode

    1. @State var selectedUmsaetze: [KontoUmsaetze.ID] = []
    Versuche diese Schritte, um sicherzustellen, dass die Auswahl in der Tabelle korrekt funktioniert und das Problem mit doppelten Einträgen vermieden wird.
  • Erst einmal superlieben Dank für die Unterstützung. Eigentlich hatte ich es auch so gemacht und habe es jetzt noch mal Step by Step nachgebaut.

    Zunächst hat es jetzt auch (einigermaßen) geklappt. Zumindest konnte ich jetzt sehen, was ich ausgewählt hatte.
    Aber: dann habe ich die Buttons über der Table angepasst. Genauer:

    Ich habe in der UmsaetzeView über dem Aufruf der UmsaetzeListView ein (paar) Buttons. Grundsätzlich auch kein Ding. Jedoch wenn ich einem der Buttons ein .disabled(selectedUmsaetze.count == 0) einfüge, dann geht die Auswahl wieder flöten.

    Es muss also irgendwie mit dem .disabled zu tun haben.

    Genauer gesagt: es muss mit einem count auf die selectedUmsaetze zu tun haben, denn auch wenn ich die Buttons alle raus schmeiße und am Ende der Table mit mit selectedUmsaetze.count nur die Anzahl der gewählten Umsätze ausgeben lassen will, dann geht es schon wieder nicht.

    Scheint mir ein Bug zu sein.