How to change background of buttons with different color when clicking the buttons inside forEach statement in SwiftUI?

戏子无情 提交于 2020-07-10 08:12:52

问题


I want to color the buttons as colors array above. For eg: if a user first selects any button then the color of that button should be orange, and if the user selects another button then it should be green and so on. The user can select upto 7 buttons from the total of 10 buttons and if 7 different buttons are selected, then they should have 7 different color.

import SwiftUI

struct ColorModel: Identifiable {
    let value: Color
    let id = UUID()
}
let colors = [
    ColorModel(value: Color.orange),
    ColorModel(value: Color.green),
    ColorModel(value: Color.blue),
    ColorModel(value: Color.red),
    ColorModel(value: Color.yellow),
    ColorModel(value: Color.gray),
    ColorModel(value: Color.pink),
]
let totalButtons: Int = 10

struct ContentView: View {
    @State private var selectedButtons = [Int]()

    var body: some View {
        ForEach(0..<totalButtons) { index in
            Button(action: {
                self.updateSelectButton(value: index)
            }) {
                Text("Button \(index)")
            }
            .background(self.selectedButtons.contains(index) ? colors[index].value : Color.white)
        }
    }

    func updateSelectButton(value: Int) {
        guard value < colors.count else {
            return
        }
        if let index = self.selectedButtons.firstIndex(of: value) {
            self.selectedButtons.remove(at: index)
        } else {
            self.selectedButtons.append(value)
        }
    }
}

The code looks like above. The problem with above code is that user can't select the 8th, 9th and 10th buttons in the array. User can only select first 7 buttons.


回答1:


You may try the following:

struct ContentView: View {
    @State private var selectedButtons = [Int]()

    var body: some View {
        ForEach(0 ..< totalButtons) { index in
            Button(action: {
                self.updateSelectButton(value: index)
            }) {
                Text("Button \(index)")
            }
            .background(self.buttonColor(value: index)) // <- extract to another function for clarity
        }
    }

    func updateSelectButton(value: Int) {
        if let index = selectedButtons.firstIndex(of: value) {
            selectedButtons.remove(at: index)
        } else if selectedButtons.count < 7 { // <- make sure we never go above 7
            selectedButtons.append(value)
        }
    }
    
    func buttonColor(value: Int) -> Color {
        if let index = selectedButtons.firstIndex(of: value), index < colors.count { // <- safety check
            return colors[index].value
        } else {
            return .white
        }
    }
}

This solution will keep the order in which you add buttons. Which means if you remove the first button you added (in orange colour) the second button will become first and will be recoloured form green to orange.

You may also want to extract the hardcoded value 7 and replace it with some variable.




回答2:


You need to remove this line of code. User can't select the 8th, 9th and 10th buttons in the array due to this line.

   guard value < colors.count else {
        return
    }

Use this code instead

    if self.selectedButtons.count >= 7 {
        return
    }

}



来源:https://stackoverflow.com/questions/62759699/how-to-change-background-of-buttons-with-different-color-when-clicking-the-butto

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