如何引用在 foreach 循环中创建的按钮

问题描述 投票:0回答:1

如何引用在 foreach 循环中创建的按钮

我有以下代码,将自定义按钮样式应用于使用 ForEach 循环创建的一组按钮。我试图做到这一点,以便发生两件事:当按下按钮时 1.如果它是正确的按钮(即与用户提示符匹配),则其边框在生成新的用户提示符之前会闪烁绿色(这是我设法实现的)大多数情况下),2.如果按钮错误,则与用户提示匹配的按钮会闪烁红色,以指示用户应该按下哪个按钮。

我尝试了两种不同的方法来创建这种效果。首先使用按下按钮时触发的函数,传入按钮边框颜色,但这不起作用,因为它不允许我指定在错误按下的情况下哪个按钮应闪烁红色。 现在我一直在尝试通过自定义按钮样式来做到这一点,但这在实践中是相似的,只是它做了更多我想要的事情。

太长了;本质上,我在引用由 forEach 循环创建的一组按钮中的单个实例时遇到了麻烦。我想象我需要在检查条件中包含第二个条件,其内容类似于“如果按钮与用户提示匹配,则仅使该按钮闪烁红色”。但不确定如何做到这一点。

这是我到目前为止所拥有的:

import SwiftUI
struct ContentView: View {
    var fullArray = ["1","2","3","4","5","6"]
    var topArray = ["1","2","3"]
    var botArray = ["4","5","6"]
    @State private var userPrompt = ["1","2","3","4","5","6"]
    @State private var newLetter = ""
    @State private var borderColor = Color.black
    @State private var letterTapped = ""
    func chosenLetter() -> String {
        return userPrompt.randomElement() ?? "Not working"
    }
    
    var body: some View {
        VStack{
            Text(newLetter)
                .padding()
                .font(.title)
                .background(Color.blue)
                .foregroundColor(.white)
            HStack {
                
                ForEach(topArray, id: \.self) { topLetter in
                    Button(action: {
                        print("Top number keys")
                    }){
                        Text(topLetter)
                    }
                    .buttonStyle(CustomButtonStyle(keyLabel: topLetter, newLetter: $newLetter, borderColor: $borderColor))

                }
                
            }
            HStack{
                ForEach(botArray, id: \.self){ botLetter in
                    Button(action:{
                        print("Bottom number keys")
                    }){
                        Text(botLetter)
                    }
                    .buttonStyle(CustomButtonStyle(keyLabel: botLetter, newLetter: $newLetter, borderColor:  $borderColor))
                }
            }
            .padding()
        }
        .onAppear {
          newLetter = chosenLetter()
        }
    }
    struct CustomButtonStyle: ButtonStyle {
        let keyLabel: String
        @State var isPressed = false
        @Binding var newLetter : String 
        @Binding public var borderColor: Color
//        @Binding var correctLetter : Bool
        
        func chooseBorder() -> Color {
            if keyLabel == newLetter {
                if isPressed{
                    return Color.green
                }
            }else{
                return Color.black
            }
            return Color.black
        }
        
        func makeBody(configuration: Configuration) -> some View {
            configuration.label
                .padding()
                .border(chooseBorder())

                .onTapGesture {
                    isPressed = true
                    // Change border color if label matches userPrompt
                    if keyLabel == newLetter {
                        borderColor = .green
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.4)
                        {
                            borderColor = Color.black
                        }

                    }else{
                        borderColor = .red
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.4)
                            {
                                borderColor = Color.black
                            }    
                    }
                }
        }
    }
}

我尝试将其作为在按钮操作中运行的函数来完成,而不是通过自定义按钮样式。 我的一个想法是我可以生成一个包含每个字符串和关联值的字典。然后,这可能允许我根据按钮的值引用该按钮。但我想我可能把它复杂化了

swift button swiftui
1个回答
0
投票

今天我们将向您展示如何实现一个漂亮的进度按钮概念。这个概念是科林·加文 (Colin Garven) 的精彩提交按钮。首先看一下它,了解需要完成哪些步骤,然后欣赏动画。该按钮背后的想法如下:单击后,提交按钮就会变成一个圆圈,并使用其边框显示进度动画。当进度动画完成时,按钮将再次展开并显示复选标记以确认提交已完成,正如 Colin 在评论中提到的那样。我们将实现这个概念,并在提交失败时添加另一种状态。

© www.soinside.com 2019 - 2024. All rights reserved.