按下按钮动画后执行按钮操作

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

我将 ButtonStyle 设置为按钮。在此按钮上,我设置了按下按钮时具有缩放效果的动画。有没有办法仅在动画完成后或延迟后执行操作?现在,当我单击按钮时,将显示下一个视图,并且您看不到动画按钮。

struct CustomButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(Color.blue)
            .padding(.vertical)
            .frame(height: 48)
            .frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
            .background(Color.white)
            .cornerRadius(32)
            .scaleEffect(configuration.isPressed ? 0.9 : 1.0)
            .opacity(configuration.isPressed ? 0.6 : 1.0)
            .animation(.easeInOut, value: configuration.isPressed)
    }
}

struct TestView: View {
   var body: some View {
     Button(action: {
          // redirect to another view
     }, label: {
          Text("Test")
     }).buttonStyle(CustomButtonStyle())
   }
}
swift button swiftui
1个回答
0
投票

如果按下按钮足够长的时间,您将能够看到缩放效果(前提是您的手指比按钮标签小)。如果您只按下按钮足够短的时间,缩小就会在达到 0.9 之前停止,并且即使您等待它完成放大,也不会很明显。 IMO,你现在拥有的已经足够好了。

如果您确实想添加延迟,则需要遵守

PrimitiveButtonStyle
,而不是
ButtonStyle
PrimitiveButtonStyle.Configuration
允许您以编程方式
trigger()
按钮的操作。但是,它不会有
isPressed
,因此您必须使用
Gesture
自行实现该部分。

struct CustomButtonStyle: PrimitiveButtonStyle {
    @State var pressed = false
    
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(Color.blue)
            .padding(.vertical)
            .frame(height: 48)
            .frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
            .background(Color.white)
            .cornerRadius(32)
            .scaleEffect(pressed ? 0.9 : 1.0)
            .opacity(pressed ? 0.6 : 1.0)
            .animation(.easeInOut, value: pressed)
            .gesture(DragGesture(minimumDistance: 0).onChanged { _ in
                pressed = true
            }.onEnded { value in
                pressed = false
                // optionally, use value.location and a geometry reader to determine whether
                // the gesture ended inside the button's label
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    configuration.trigger()
                }
            })
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.