自定义 Button 按钮, 圆角 & 阴影 & disable\normal状态 & 点击动画 & 点击动效
效果图
定义部分
import SwiftUI
struct RoundedAndShadowButton: View {
private let kscreenWidth: CGFloat = UIScreen.main.bounds.width
private let kscreenHeight: CGFloat = UIScreen.main.bounds.height
@State private var showProgress: Bool = false
var title: String = ""
let action: () -> Void
var disabled: Bool = false
var imageName: String = ""
var body: some View {
ZStack(alignment: .center) {
Button {
showProgress = true
after()
action()
} label: {
if !showProgress {
Label {
Text(title)
.foregroundStyle(.white)
.frame(width: kscreenWidth - 90, height: 50) // 此尺寸决定了按钮可点击size
} icon: {
if imageName != "" {
Image(systemName: imageName)
}
}
}
}
.frame(width: kscreenWidth - 90, height: 50)
// .buttonStyle(.roundedAndShadow) // 阴影
.background(
RoundedRectangle(cornerRadius: 10)
.foregroundStyle(disabled ? Color("btn_primary_disabled_bg_color"):Color("btn_primary_default_bg_color"))
)
.disabled(disabled)
if showProgress {
ProgressView()
.progressViewStyle(.circular)
.tint(.white)
}
}
}
func after() {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) {
showProgress = false
}
}
}
#Preview {
RoundedAndShadowButton(action: {})
}
struct RoundedAndShadowButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundStyle(.white)
.padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
.compositingGroup()
.shadow(radius: configuration.isPressed ? 0:5, x: 0, y: configuration.isPressed ? 0:3)
.scaleEffect(configuration.isPressed ? 0.95:1)
.animation(.spring(), value: configuration.isPressed)
}
}
// 快捷引用
extension ButtonStyle where Self == RoundedAndShadowButtonStyle {
static var roundedAndShadow:RoundedAndShadowButtonStyle {
RoundedAndShadowButtonStyle()
}
}

调用
RoundedAndShadowButton(title: "Log in", action: {
print("Log in")
}, disabled: buttonIsDisabled)
.onReceive(viewModel.submitAllowed) { submitAllowed in
self.buttonIsDisabled = !submitAllowed
}