SwiftUI笔记-修改Button样式及点击动画

1,508 阅读2分钟

前言

最近一段时间接触了一些SwiftUI相关的知识,在使用的过程中发现中文资料相对来说还是比较少,刚好遇到一个修改Button点击动画的需求,于是记录下来,方便以后查找。

SwiftUI中,Button是一个很常见的View。默认情况下,Button会有一个蓝色的前景色,同时点击时会有一个淡入淡出的动画。

 var body: some View {
        Button {
            debugPrint("Hello World!")
        } label: {
            Text("Click me")
        }
    }

ezgif.com-gif-maker.gif

如果想要修改上述的默认行为,这时就要使用ButtonStyle了。

场景1:修改Button 文字前景色

ButtonStyle是一个官方提供的协议,通过实现此协议,我们就能够在对应的方法中获取到Button中设置的label,从而对其设置想要的显示效果。

当然,如果仅仅是修改前景色等类似的需求的话,可以在Button中的label里面设置就可以了。这里使用ButtonStyle主要是为了方便代码的复用。

struct Test: View {
    var body: some View {
        Button {
            debugPrint("Hello World!")
        } label: {
            Text("Click me")
        }
        .buttonStyle(CustomButtonStyle())
    }
}

struct CustomButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
             // 设置前景色
            .foregroundColor(.white)
            .padding()
            .background(Color.green)

    }
}

image.png

场景2:为 Button 添加渐变

和场景1的实现类似,只是在background中添加了一个渐变,这里为了示意直接使用了线形渐变。

struct CustomButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(.white)
            .padding()
            // 设置渐变背景色
            .background(LinearGradient(colors: [Color.red, Color.green], startPoint: .leading, endPoint: .trailing))
            // 添加圆角
            .cornerRadius(12)
    }
}

image.png

场景3:修改 Button 点击动画

默认情况下,Button点击时就是一个如上文所示的淡入淡出动画,如果进行定制化,也可以实现ButtonStyle协议。

在需要实现的makeBody方法中,我们不仅能够获取到设置的label,还能够获取到一个很重要的状态——isPressed,根据这个状态,我们就能够轻松的定义出想要的效果了。

这里定义了一个点击放大的效果

struct CustomButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(.white)
            .padding()
            // 设置渐变背景色
            .background(LinearGradient(colors: [Color.red, Color.green], startPoint: .leading, endPoint: .trailing))
            // 添加圆角
            .cornerRadius(12)
            // 根据点击状态设置 scale
            .scaleEffect(configuration.isPressed ? 1.5 : 1)
            // 设置动画参数
            .animation(.easeInOut, value: configuration.isPressed)
    }
}

Apr-21-2022 16-28-11.gif

上面的代码中使用了一个easeInOut(先慢后快)的动画参数,可以根据实际需求选择合适的动画参数,比如如果需要一个弹性动画,可以使用spring()来定义出想要的效果。

总结

SwiftUI提供了一个ButtonStyle协议用于自定义Button的外观样式和动画交互,其中两个核心的参数是labelisPressed。前者可以直接修改Button的显示,后者可以根据当前的按压状态做出需要的交互效果,通过这种方式,能够极大的提升按钮的灵活性和复用性。