前言
最近一段时间接触了一些SwiftUI
相关的知识,在使用的过程中发现中文资料相对来说还是比较少,刚好遇到一个修改Button
点击动画的需求,于是记录下来,方便以后查找。
在SwiftUI
中,Button
是一个很常见的View
。默认情况下,Button
会有一个蓝色的前景色,同时点击时会有一个淡入淡出的动画。
var body: some View {
Button {
debugPrint("Hello World!")
} label: {
Text("Click me")
}
}
如果想要修改上述的默认行为,这时就要使用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)
}
}
场景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)
}
}
场景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)
}
}
上面的代码中使用了一个easeInOut
(先慢后快)的动画参数,可以根据实际需求选择合适的动画参数,比如如果需要一个弹性动画,可以使用spring()
来定义出想要的效果。
总结
SwiftUI
提供了一个ButtonStyle
协议用于自定义Button
的外观样式和动画交互,其中两个核心的参数是label
和isPressed
。前者可以直接修改Button
的显示,后者可以根据当前的按压状态做出需要的交互效果,通过这种方式,能够极大的提升按钮的灵活性和复用性。