微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何为在 forEach 循环内点击的按钮设置动画?

如何解决如何为在 forEach 循环内点击的按钮设置动画?

我试图在用户点击按钮时为按钮设置动画。它在侧面偏移,使其看起来像是被按下了。

如果您查看图像,您应该明白为什么我要通过偏移来为其设置动画,因为我在按钮后面有一个偏移的背景,并且按钮在单击时应与该框架匹配。

当前按钮在点击时如图所示动画,但所有按钮动画都被按下并且在点击发生后它们不会返回到原始位置。

点击前的按钮

Button before clicked

点击后按钮

Button after click

下面是按钮数组:

@State private var isClicked = false
    
    
    let buttons: [[CalcButton]] = [
        [.clear,.plusMinus,.percent,.divide],[.seven,.eight,.nine,.multiply],[.four,.five,.six,.minus],[.one,.two,.three,.add],[.zero,.doubleZero,.decimal,.equals]
    ]
ForEach(buttons,id: \.self) { row in
    HStack(spacing: 20) {
        ForEach(row,id: \.self) { item in
            Button(action: {
                withAnimation {
                    self.animation()
                }
            },label: {
                ZStack {

                    Rectangle()
                        .frame(width: buttonWidth(button: item),height: buttonHeight())
                        .foregroundColor(.backgroundColor)
                        .offset(x: 7.0,y: 7.0)

                    Rectangle()
                        .frame(width: buttonWidth(button: item),height: buttonHeight())
                        .foregroundColor(.white)


                    Text(item.rawValue)
                        .font(.custom("ChicagoFLF",size: 27))
                        .frame(width: buttonWidth(button: item),height: buttonHeight())
                        .foregroundColor(.backgroundColor)
                        .border(Color.backgroundColor,width: 4)
                        .offset(x: isClicked ? 7 : 0,y: isClicked ? 7 : 0)

                }

            })

        }
    }
    .padding(.bottom,10)

}

这是切换 isClicked 状态变量的函数

func animation() {
    self.isClicked.toggle()
}

解决方法

您需要为每个按钮设置一个选择状态。所以最好创建一个自定义按钮。

这是演示版代码。

自定义按钮视图

struct CustomButton: View {
    var text: String
    var action: () -> Void
    
    @State private var isPressed = false
    
    var body: some View {
        Button(action: {
            // Do something..
        },label: {
            ZStack {
                Rectangle()
                    .foregroundColor(.black)
                    .offset(x: 7.0,y: 7.0)
                
                Rectangle()
                    .foregroundColor(.white)
                
                Text(text)
                    .frame(width: 50,height: 50)
                    .foregroundColor(.black)
                    .border(Color.black,width: 4)
                    .offset(x: isPressed ? 7 : 0,y: isPressed ? 7 : 0)
            }
            
        })
        .buttonStyle(PlainButtonStyle())
        .simultaneousGesture(
            DragGesture(minimumDistance: 0)
                .onChanged({ _ in
                    // Comment this line if you want stay effect after clicked
                    isPressed = true
                })
                .onEnded({ _ in
                    isPressed = false
                    // // Uncomment below line and comment above line if you want stay effect after clicked
                    //isPressed.toggle()
                    action()
                })
        )
        .frame(width: 50,height: 50)
    }
}

用法:

struct DemoView: View {
    var body: some View {
        HStack(spacing: 10) {
            ForEach(0..<10) { index in
                CustomButton(text: index.description) {
                    print("Action")
                }
            }
        }
    }
}

enter image description here

如果你想在点击后保持你的效果。只需替换此代码部分即可。

.simultaneousGesture(
            DragGesture(minimumDistance: 0)
                .onChanged({ _ in
                })
                .onEnded({ _ in
                    isPressed.toggle()
                    action()
                })
        )

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。