SwiftUI 2.0 : export images with . 文件导出器修饰符

标签 swiftui ios14 xcode12 macos-big-sur

目标:使用新的 .fileExporter 修饰符通过 SwiftUI 导出图像

问题:目标图像未传递到 .fileExporter 文档。

问题:如何使用 .fileExporter 修饰符导出图像?

struct ContentView: View {
    
    @State private var openFile = false
    @State private var exportFile = false


    @State private var img1 = UIImage()
    @State private var img2 = UIImage()

    @State private var target: Binding<UIImage>?    // dynamic target for importer
    
    var body: some View {
        Form {
            //image 1
            Button(action: {
                    self.target = $img1
                self.openFile.toggle()
            }){
                
                Image(uiImage: self.img1)
                .renderingMode(.original)
                .resizable()
                .frame(width: 48, height: 48)
                .clipShape(Circle())
            }
            
            //image 2
            Button(action: {
                    self.target = $img2
                self.openFile.toggle()
            }){
                
                Image(uiImage: self.img2)
                .renderingMode(.original)
                .resizable()
                .frame(width: 48, height: 48)
                .clipShape(Circle())
            }
        }
        .navigationTitle("File Importer")


        //file exporter not working. not sure what I should input as "document"
        .fileExporter(isPresented: $exportFile, document: target, contentType: .image) { result in
            if case .success = result {
                // Handle success.
            } else {
                // Handle failure.
            }
        }

        //file importer
        .fileImporter(isPresented: $openFile, allowedContentTypes: [.image]) { (res) in
            do{
                let fileUrl = try res.get()
                print(fileUrl)
                
                guard fileUrl.startAccessingSecurityScopedResource() else { return }
                if let imageData = try? Data(contentsOf: fileUrl),
                let image = UIImage(data: imageData) {
                    self.target?.wrappedValue = image
                }
                fileUrl.stopAccessingSecurityScopedResource()
                
            } catch{
                
                print ("error reading")
                print (error.localizedDescription)
            }
        }
    }
}

最佳答案

我发现了一些代码问题和一些逻辑问题。这是我编辑的版本:

struct ContentView: View {
    
    @State private var openFile = false
    @State private var exportFile = false


    @State private var img1 = UIImage(named: "0")!
    @State private var img2 = UIImage(named: "1")!

    @State private var target : UIImage?
    
    var body: some View {
        Form {
            //image 1
            Button(action: {
                self.target = img1
                self.exportFile.toggle()
                //self.openFile.toggle()
            }){
                
                Image(uiImage: self.img1)
                .renderingMode(.original)
                .resizable()
                .frame(width: 48, height: 48)
                .clipShape(Circle())
            }
            
            //image 2
            Button(action: {
                self.target = img2
                self.exportFile.toggle()
                //self.openFile.toggle()
            }){
                
                Image(uiImage: self.img2)
                .renderingMode(.original)
                .resizable()
                .frame(width: 48, height: 48)
                .clipShape(Circle())
            }
        }
        .navigationTitle("File Importer")

        .fileExporter(isPresented: $exportFile, document: ImageDocument(image: target), contentType: .png, onCompletion: { (result) in
            if case .success = result {
                print("Success")
            } else {
                print("Failure")
            }
        })


        //file importer
        .fileImporter(isPresented: $openFile, allowedContentTypes: [.image]) { (res) in
            do{
                let fileUrl = try res.get()
                print(fileUrl)
                
                guard fileUrl.startAccessingSecurityScopedResource() else { return }
                if let imageData = try? Data(contentsOf: fileUrl),
                let image = UIImage(data: imageData) {
                    self.target = image
                }
                fileUrl.stopAccessingSecurityScopedResource()
                
            } catch{
                
                print ("error reading")
                print (error.localizedDescription)
            }
        }
    }
}

struct ImageDocument: FileDocument {
    
    static var readableContentTypes: [UTType] { [.png] }

    var image: UIImage

    init(image: UIImage?) {
        self.image = image ?? UIImage()
    }

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,
              let image = UIImage(data: data)
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        self.image = image
    }

    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        return FileWrapper(regularFileWithContents: image.pngData()!)
    }
    
}

需要注意的事项:

  1. 逻辑错误:您有一个exportFile状态变量,但你从未修改过它。这意味着 fileExporter永远不会出现。
  2. 您正在传递 Binding<UIImage>到一个需要 FileDocument 的函数。我写了一个简单的FileDocument图像的实现。
  3. 因为我关掉了你的openFile切换为 exportFile ,您现在没有 openFile使用权。这是一个逻辑决定,您需要弄清楚何时/如何触发这些。
  4. 我也没有对图像进行任何错误处理,并决定将所有内容都视为 PNG。您可能想要做出不同的选择。

请注意,我还使用了名为“0”和“1”的图像——这些图像特定于我的示例项目。更改它们以适合您的项目。

如果您想要不同类型的解决方案,您还可以考虑使用 \.exportFiles行动:https://www.hackingwithswift.com/quick-start/swiftui/how-to-export-files-using-exportfilesaction

关于SwiftUI 2.0 : export images with . 文件导出器修饰符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65993146/

相关文章:

ios - Xcode 12. 无法使用不可用的运行时进行查找

ios - Flutter - 代码签名 "App.framework"失败

animation - 在 SwiftUI 中链接动画

scrollview - 如何在SwiftUI ScrollView中以编程方式检测滚动方向

swift - 从iOS的Core Data 14 WidgetKit 中获取数据

swift - Xcode 12 和 iOS 14 中的手势问题

swiftui - 在列表 (SwiftUI) 中导航回后,所选列表行的背景保持灰色(选中)。 iOS14 + Xcode12

ios - SwiftUI SceneDelegate 问题

ios - SwiftUI无法在Bundle中找到图像,但是图像在正确的路径中?

flutter - flutter :在 Debug模式下构建时,运行pod安装将永远花费