How can my selection go right in the list I created in SwiftUI

纵然是瞬间 提交于 2021-01-27 12:29:55

问题


I created the list showing the array of digits. When you select multiple digits and hit the button below, it should tell you the sum of the selected digits.

However, when you select the same digits in the different rows, both of them get checked at a time. I understand that this should be fixed by using UUID, but the final result that I want is the sum of the digits, which is Int. Therefore, I have been lost... Can someone tell me how to make it right, please?

Also, the last row doesn't get checked even when selected for some reason, which is so weird. Here is the link to the gif showing the current situation and the entire code below.

import SwiftUI

struct MultipleSelectionList: View {
    
    @State var items: [Int] = [20, 20, 50, 23, 3442, 332]
    @State var selections: [Int] = []
    @State var result: Int = 0

    var body: some View {
        VStack {
            List {
                ForEach(items, id: \.self) { item in
                    MultipleSelectionRow(value: item, isSelected: self.selections.contains(item)) {
                        if self.selections.contains(item) {
                            self.selections.removeAll(where: { $0 == item })
                        }
                        else {
                            self.selections.append(item)
                        }
                    }
                }
            }
            
            Button(action: {
                result = selections.reduce(0, +)
            }, label: {
                Text("Show result")
            })
            .padding()
            
            Text("Result is \(result)")
            Text("The number of items in the array is \(selections.count)")
                .padding()
            Spacer()
        }
        
        
    }
}

struct MultipleSelectionRow: View {
    var value: Int
    var isSelected: Bool
    var action: () -> Void

    var body: some View {
        Button(action: self.action) {
            HStack {
                Text("\(self.value)")
                if self.isSelected {
                    Spacer()
                    Image(systemName: "checkmark")
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        MultipleSelectionList()
    }
}

回答1:


You could just store the index of the items in selections, instead of the actual items.

You could do something like:

ForEach(items.indices) { i in
   MultipleSelectionRow(value: items[i], isSelected: self.selections.contains(i)) {
                        if self.selections.contains(i) {
                            self.selections.removeAll(where: { $0 == i })
                        }
                        else {
                            self.selections.append(i)
                        }
                    }

}

I have not run this so there may be errors but you get the idea.




回答2:


Before you look at the code below try making your items: [Int] into a items: [UUID: Int] this would mimic having an Identifiable object.

Programming is about figuring how to make things happen.

import SwiftUI

struct MultipleSelectionList: View {
    
    @State var items: [UUID:Int] = [UUID():20, UUID():20, UUID():50, UUID():23, UUID():3442, UUID():332]
    @State var selections: [UUID:Int] = [:]
    @State var result: Int = 0
    
    var body: some View {
        VStack {
            List {
                ForEach(items.sorted(by: { $0.1 < $1.1 }), id: \.key) { key, value in
                    MultipleSelectionRow(value: value, isSelected: self.selections[key] != nil) {
                        if self.selections[key] != nil {
                            self.selections.removeValue(forKey: key)
                        }
                        else {
                            self.selections[key] = value
                        }
                    }
                }
            }
            
            Button(action: {
                result = selections.values.reduce(0, +)
            }, label: {
                Text("Show result")
            })
            .padding()
            
            Text("Result is \(result)")
            Text("The number of items in the array is \(selections.count)")
                .padding()
            Spacer()
        }
        
        
    }
}

struct MultipleSelectionRow: View {
    var value: Int
    var isSelected: Bool
    var action: () -> Void
    
    var body: some View {
        Button(action: self.action) {
            HStack {
                Text("\(self.value)")
                if self.isSelected {
                    Spacer()
                    Image(systemName: "checkmark")
                }
            }
        }
    }
}

struct MultipleSelect_Previews: PreviewProvider {
    static var previews: some View {
        MultipleSelectionList()
    }
}


来源:https://stackoverflow.com/questions/65238064/how-can-my-selection-go-right-in-the-list-i-created-in-swiftui

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!