我将ButtonStyle设置为按钮.在这个按钮上,我设置了一个按下按钮时具有zoom 效果的动画.有没有一种方法可以在动画完成后才执行动作,或者可能延迟执行?现在,当我单击该按钮时,将显示下一个视图,您无法看到该按钮的动画效果.

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

推荐答案

如果你按住按钮足够长的时间,你将能够看到zoom 效果(假设你的手指比按钮标签小).如果只按下按钮足够短的时间,缩小将在达到0.9之前停止,即使你等待它完成缩小,也不会非常明显.国际海事组织,你现在拥有的已经足够好了.

如果您真的想添加延迟,则需要符合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()
                }
            })
    }
}

Swift相关问答推荐

Accelerate的SparseMultiply随机崩溃,EXC_BAD_ANCE

如何将趋势线添加到线性图中?

什么是Swift Concurrency中任务组的正常退出

如何更新Square Order?

如何在visionOS上删除PhotosPicker背景 colored颜色 ?

在数组中查找最大y值的x值

可以';t在标记为@Observable的类上使用属性包装

如何在 swiftui 中设置给定字符串类型日期的日期倒计时?

从 Swift 列表中的行中检索值

如何更改任务栏 colored颜色 和 sf 符号 colored颜色 ?

如何更改 Picker 的边框 colored颜色

Swift - 如何更新多目录中的对象

无法使用锚激活约束

SwiftUI 中的 .primary 和 .secondary colored颜色 是什么?

Swift 5.0 编译器无法导入使用 Swift 4.2.1 编译的模块

subscribeOn 和 observeOn 的顺序重要吗?

使用 phimagemanager 将图像保存到自定义相册?

如何在 SwiftUI 中以编程方式滚动列表?

在 unwind segue 之后执行 push segue

Swift if 语句 - 多个条件用逗号分隔?