在SwiftUI中单击forEach语句内的按钮时,如何更改不同颜色的按钮背景?

时间:2020-07-06 15:49:22

标签: ios swift xcode swiftui swift5

我想为按钮上色为颜色数组。例如:如果用户首先选择任何按钮,则该按钮的颜色应为橙色,如果用户选择另一个按钮,则其应为绿色,依此类推。用户可以从总共10个按钮中最多选择7个按钮,如果选择了7个不同的按钮,则它们应该具有7种不同的颜色。

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)
        }
    }
}

代码类似于上面。 上面代码的问题是用户无法选择数组中的第8,第9和第10个按钮。用户只能选择前7个按钮。

2 个答案:

答案 0 :(得分:2)

您可以尝试以下操作:

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
        }
    }
}

此解决方案将保持您添加按钮的顺序。这意味着,如果您删除添加的第一个按钮(橙色),则第二个按钮将成为第一个,并从绿色变为橙色。

您可能还希望提取硬编码的值7并将其替换为某些变量。

答案 1 :(得分:0)

您需要删除此行代码。由于此行,用户无法选择数组中的第8,第9和第10个按钮。

   guard value < colors.count else {
        return
    }

改为使用此代码

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

}