简体   繁体   中英

SwiftUI - hide list items using Toggle

I have found almost the perfect code for my needs. But there is one problem:

I would like to use toggles in each row instead of buttons.

Original code posted by @kontiki here: SwiftUI hide list item from list item view

import SwiftUI

struct Item: Identifiable {
    let id = UUID()
    var isComplete: Bool = false
}

class Model: ObservableObject {
    @Published var isOn: Bool = false
    @Published var arr = [Item(isComplete: true), Item(isComplete: false), Item(isComplete: true), Item(isComplete: false), Item(isComplete: true), Item(isComplete: true)]
}

struct ContentView: View {
    @ObservedObject var model = Model()

    var body: some View {
        List {

            Toggle(isOn: $model.isOn) { Text("Toggle") }

            ForEach(self.model.arr.filter { model.isOn ? true : $0.isComplete }) { item in
                Row(item: item, model: self.model)
            }
        }
    }
}

struct Row: View {
    let item: Item
    @ObservedObject var model: Model

    var body: some View {
        HStack {

            Button(action: {

                if let idx = self.model.arr.firstIndex(where: { $0.id == self.item.id }) {
                    self.model.arr[idx].isComplete.toggle()
                    self.model.isOn = false
                }

            }) {

                Text("Button")

            }

            Text(item.isComplete ? "Complete" : "Not complete")

        }
    }
}

Instead of button I have tried to use toggle like this:

Toggle(isOn: $item.isComplete) {
                Text("Done")
            }

There is this if statement inside button that I don't understand. I have tried to take this let idx declaration outside of button too to make it easier for using toggle (as I don't know how to make such complicated toggle) but this also failed.

Note: There is known issue with Toggle control update in List. Please be aware. The details are in Problems with layout of some rows in SwiftUI list topic.

Here is possible approach. Modified lines are marked in comments.

import SwiftUI

struct Item: Identifiable, Equatable { // <<
    let id = UUID()
    var isComplete: Bool = false
}

class Model: ObservableObject {
    @Published var isOn: Bool = false
    @Published var arr = [Item(isComplete: true), Item(isComplete: false), Item(isComplete: true), Item(isComplete: false), Item(isComplete: true), Item(isComplete: true)]
}

struct ContentView: View {
    @ObservedObject var model = Model()

    var body: some View {
        List {

            Toggle(isOn: $model.isOn) { Text("Toggle") }

            ForEach(self.model.arr.filter { model.isOn ? true : $0.isComplete }) { item in
                Row(item: self.$model.arr[self.model.arr.firstIndex(of: item)!]) // <<
            }
        }
    }
}

struct Row: View {
    @Binding var item: Item // <<

    var body: some View {
        HStack {
            Toggle(isOn: $item.isComplete) {
                Text("Done")
            }
            Text(item.isComplete ? "Complete" : "Not complete")

        }
    }
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM