【问题标题】:Show ProgressView when Exporting File in SwiftUI在 SwiftUI 中导出文件时显示 ProgressView
【发布时间】:2021-10-13 12:41:25
【问题描述】:

我在尝试导出文件时尝试显示 ProgressView。该文件是一个大文件,我正在使用fileExporter 修饰符。在 ZStack 中拥有 ProgressView 并将 zIndex 设置为 1 不起作用。我还尝试将长操作(获取文档)放入 DispatchQueue 但挑战在于它不是视图并且无法编译。以下是我目前拥有的代码。

这是我所期待的: 在我按下“导出文件”按钮后,我应该在创建文档时看到一个旋转的圆圈(在本例中是模拟长时间操作的 2 秒睡眠命令)。 之后应该显示来自 fileExporter 的“移动”表

非常感谢任何帮助。

这是一个示例应用程序:

struct ContentView: View {
    @State private var isExporting: Bool = false

    var body: some View {
        VStack {
            Button(action: {
                isExporting = true
            }, label: {
                Text("Export File")
            })
                .padding()
            if isExporting {
                ProgressView() {
                    ZStack{}
                    .fileExporter(isPresented: $isExporting, document: FileExport(contents: "This is a simple Text"), contentType: .plainText) { result in
                        if case .success = result {
                            print(try! result.get())
                            print("File Saved")
                        } else {
                            print("File Not Saved")
                        }
                    }
                }
            }
        }
    }
}

struct FileExport: FileDocument {
    static var readableContentTypes: [UTType] {[.plainText]}
    
    var contents: String
    
    init(contents: String) {
        self.contents = contents
        sleep(2) // simulate a long operation
    }
    
    init(configuration: ReadConfiguration) throws {
        contents = ""
    }
    
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        return FileWrapper(regularFileWithContents: contents.data(using: .utf8)!)
    }
}

【问题讨论】:

  • 什么是UTType?我的 xcode 说在范围内找不到类型“UTType”!你的xcode版本是什么?我应该导入一些东西吗?
  • @swiftPunk UTTypeUniformTypeIdentifiers 包的一部分:import UniformTypeIdentifiers

标签: ios swift swiftui


【解决方案1】:

您的代码中存在一些问题。首先,您的ProgressView() 实际上并不包含在ZStack 中。您显示的唯一ZStack 不包含任何内容,因为内容必须在花括号内。在这种情况下,您通常可以将整个视图包裹在 ZStack 中。

接下来,您自己的视图通常不会采用这样的尾随闭包。您没有包含 ProgressView 代码,但是您显示的代码作为尾随闭包是荒谬的,所以我认为这不是您的意图。因此,我将打开的大括号移除为适当的关闭大括号。

说完所有这些后,视图将显示,但仍位于文件导出窗口下方。我从来没有找到任何将视图放置在这样的操作系统表上方的方法。如果是您的工作表,我已经看到了一些“解决方案”,但它们并不是真正推荐的。

此外,我不确定您如何获取数据以显示进度视图,而不仅仅是作为一个连续的微调器。我在文档中找不到 Apple 允许您访问该数据的任何地方。

最后,因为您将进度视图键入isPresented var isExporting 意味着您的ProgressView() 将在FileExport 表执行时关闭。

此外,虽然它似乎与条件 if 块内的 .fileExporter 一起使用,但我感觉不对,我会将其移至视图的另一部分。这似乎是一种不好的做法。

FWIW,这里是“工作”代码,但我看不出你如何才能真正实现你的目标:

struct FileExporter: View {
    @State private var isExporting: Bool = false
    
    var body: some View {
        ZStack {
            VStack {
                Button(action: {
                    isExporting = true
                }, label: {
                    Text("Export File")
                })
                    .padding()
                
                if isExporting {
                    ProgressView() // { No brace would go here
                        .fileExporter(isPresented: $isExporting, document: FileExport(contents: "This is a simple Text"), contentType: .plainText) { result in
                            if case .success = result {
                                print(try! result.get())
                                print("File Saved")
                            } else {
                                print("File Not Saved")
                            }
                        }
                }
            }
        }
    }
}

如果您想实现一个显示进度视图(条形图或微调器)的解决方案,我认为您必须自己动手。

【讨论】:

  • 感谢您的建议。但是,这并不能解决问题!我希望在 fileExporter 呈现“移动”表之前创建文档之前看到一个旋转的圆圈
  • 你希望在哪里看到旋转的圆圈?
  • 我希望它会在“移动”屏幕出现之前显示在“导出文件”的顶部。
  • 这是我认为你做不到的。据我了解,像这样的 Apple 工作表是系统工作表,因此它们存在于您的应用程序之外。因此,您不能在它们上放置ZStack.overlay 并在顶部放置视图。而且,它也将在您的应用之外进行处理。
【解决方案2】:

这是一个可能的解决方案。可能有更好的方法来做到这一点!我正在使用ZStack{} 附加fileExporter。有没有不同的方法或其他解决方案?

struct ContentView: View {

    @State private var isExporting: Bool = false
    @State private var isLoading: Bool = false
    @State private var document: FileExport? = nil
    
    var body: some View {
        VStack {
            Button(action: {
                isExporting = true
                isLoading = true
                DispatchQueue.global(qos: .background).async {
                    document = FileExport(contents: "This is a simple text")
                    
                    DispatchQueue.main.async {
                        isLoading = false
                    }
                }
            }, label: {
                Text("Export File")
            })
                .padding()
            
            if isLoading {
                ProgressView()
                    .zIndex(1.0)
            }
            
            if isExporting && !isLoading {
                ZStack {}
                    .fileExporter(isPresented: $isExporting, document: document, contentType: .plainText) { result in
                        if case .success = result {
                            print(try! result.get())
                            print("File Saved")
                        } else {
                            print("File Not Saved")
                        }
                    }
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2022-07-03
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    相关资源
    最近更新 更多