更新警报消息中的文本

问题描述 投票:0回答:1

我目前正在使用 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 更新文本,因为我不想使用已弃用的版本。 提前谢谢:-)

swift swiftui alert
1个回答
0
投票

版本

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)
}

Animation

© www.soinside.com 2019 - 2024. All rights reserved.