我目前正在使用 SwiftUI 开发一个对话框,我想在警报消息中分享下载进度。所以它会更新最后的百分比文本。我使用了旧的已弃用的警报版本和新版本,并且我在这两个版本上都面临着不同的行为。
旧的已弃用 API
.alert(isPresented: $showingAlert) {
Alert(title: Text("Prepare download"),
message: Text("The video will be downloaded ... (\(viewModel.formattedProgressInPercent()))"),
dismissButton: .cancel(Text("Cancel")) {
viewModel.onCancelDownloadTaped()
}
)
}
这是新的 API
.alert("Prepare download",
isPresented: $showingAlert, actions: {
Button("Cancel", role: .cancel) {
viewModel.onCancelDownloadTaped()
}
}, message: {
Text("The video will be downloaded ... (\(viewModel.formattedProgressInPercent))")
}
)
新的 API 无法更新文本。
也许有人知道如何实现我也可以使用新 API 更新文本,因为我不想使用已弃用的版本。 提前谢谢:-)
版本
alert(_:isPresented:presenting:actions:message:)
提供了另一种呈现警报的方式。这也接受数据呈现,但文档指出:
演示发生后数据不应更改。您在演示后所做的任何更改都将被忽略。
因此,没有数据的版本也不允许动态更新,这也许并不奇怪。
另一种解决方法是创建您自己的自定义警报,而不是返回到已弃用的版本。然后,您可以显示您喜欢的任何信息,并以您喜欢的方式设计它。
ZStack
的顶层。这是一个看起来和行为都非常像本机警报的示例:
@State private var showingAlert = false
@State private var progress = 0
private var progresAlert: some View {
VStack(spacing: 1) {
VStack(spacing: 6) {
Text("Downloading...")
.font(.headline)
Text("Progress: \(progress)")
.font(.footnote)
}
.padding()
.frame(minHeight: 80)
Divider()
HStack(spacing: 0) {
Button("Cancel", role: .cancel) {
// ...
showingAlert = false
}
.fontWeight(.semibold)
.frame(maxWidth: .infinity)
Divider()
Button("Start again", role: .none) {
// ...
showingAlert = false
}
.frame(maxWidth: .infinity)
}
.buttonStyle(.borderless)
.frame(maxHeight: 44)
}
.frame(maxWidth: 270)
.background {
RoundedRectangle(cornerRadius: 10)
.fill(.background)
}
}
var body: some View {
ZStack {
// main content
if showingAlert {
Color.black
.opacity(0.2)
.ignoresSafeArea()
.onTapGesture { showingAlert = false }
.transition(.opacity.animation(.easeInOut(duration: 0.2)))
progresAlert
.transition(
.scale(0.8).combined(with: .opacity)
.animation(.spring(duration: 0.25))
)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}