我在 Swiftui 中有一个按钮。单击该按钮时,该按钮将开始运行。
private struct Button1: View {
@State var isLoading = false
var body: some View {
Button("Hello") {
isLoading.toggle()
}
.buttonStyle(ProgressButtonStyle(isLoading: $isLoading))
}
}
我为按钮的进度创建了自定义按钮样式。
truct ProgressButtonStyle: PrimitiveButtonStyle {
@Binding var isLoading: Bool
@Environment(\.isEnabled) var isEnabled
func makeBody(configuration: PrimitiveButtonStyleConfiguration) -> some View {
Button(action: { dispatchTrigger(configuration) }) {
configuration
.label
.opacity(contentOpacity)
}
.buttonStyle(.base)
.overlay(progressViewOverlay())
}
@ViewBuilder func progressViewOverlay() -> some View {
isLoading ? ProgressView().tint(progressTintColor) : nil
}
var progressTintColor: Color {
if isEnabled {
return .white
} else {
return Color(.tertiaryLabel)
}
}
var contentOpacity: Double {
isLoading ? 0.0 : 1.0
}
private func dispatchTrigger(_ configuration: Configuration) {
guard !isLoading else { return }
configuration.trigger()
}
}
当我用另一个按钮控制按钮的外观时,没有问题。但是当我签入同一个按钮时,按钮的文本很晚才消失。我怎么解决这个问题? 我已经添加了这种情况的视频。
看起来像是应用了动画效果。解决方法是使用按钮样式的 makeBody 函数中的事务修饰符确保动画为 nil。这对我有用,文本会立即使用 iphone 进行转换。在 MacOS 上似乎没有动画,因此无论有无动画都可以使用。之前的修饰符 .animation(nil) 已经在 ios15 中弃用了。
func makeBody(configuration: PrimitiveButtonStyleConfiguration) -> some View {
Button(action: { dispatchTrigger(configuration) }) {
configuration
.label
.opacity(contentOpacity)
.transaction({ transaction in // Transition modifier here.....
transaction.animation = nil
})
}
.overlay(progressViewOverlay())
.buttonStyle(.bordered)
}
更多信息和信用:https://www.avanderlee.com/swiftui/disable-animations-transactions/