【问题标题】:SwiftUI 2.0: export group of images with .fileExporter modifierSwiftUI 2.0:使用 .fileExporter 修饰符导出图像组
【发布时间】:2021-02-04 13:02:32
【问题描述】:

这是对该线程的跟进: SwiftUI 2.0: export images with .fileExporter modifier

目标:在 SwiftUI 中导出一组图片

我做了什么: 我正在使用带有 FileDocument 结构的 .fileExporter 修饰符。 也对其他方法开放,例如 .例如 fileMover 修饰符。

问题: 在为多个图像结构设置 FileDocument 时,我在 func fileWrapper 上遇到错误(检查代码如下)。

问题: 如何在 SwiftUI 中导出多个图像(可以是任何方法)?

    //file exporter
    .fileExporter(isPresented: $exportFile, document: ImageDocument(
                    
                    
                    image: UIImage(data: product.cover ?? Data())!,
                    image2:  UIImage(data: product.cover2 ?? Data())!)
                  
                  ,
           
contentType: .jpeg, onCompletion: { (result) in
            if case .success = result {
                
                print("Success")
            } else {
                print("Failure")
            }
        })
//export group of images
struct ImageDocument: FileDocument {
    
    static var readableContentTypes: [UTType] { [.jpeg] }

    var image: UIImage
    var image2: UIImage


    init(
        image: UIImage?,
        image2: UIImage?
    ) {
        
        self.image = image ?? UIImage()
        self.image2 = image2 ?? UIImage()

    }
    


    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,
              let image = UIImage(data: data),
              let image2 = UIImage(data: data)

        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        self.image = image
        self.image2 = image2

    }

    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        return FileWrapper(regularFileWithContents:
                            image.jpegData(compressionQuality: 0.80)!,
                            image2.jpegData(compressionQuality: 0.80)!//<----- getting an "extra argument error here
                            )
    }
    
}

更新: 试图重写 UIImage 的 Max 答案,但这只会导出 1 张图片:


import SwiftUI

class AppContext: ObservableObject {
    @Published var fileSaveDialogShown = false
}

@main
struct FocalApp: App {
  @StateObject var appContext = AppContext()

  var body: some Scene {
    WindowGroup {
      ContentView()
        .environmentObject(self.appContext)
        .fileExporter(
          isPresented: $appContext.fileSaveDialogShown,
          documents: [
            ImageDocument(image: UIImage(named: "1")),
            ImageDocument(image: UIImage(named: "2"))
          ],
          contentType: .jpeg // Match this to your representation in ImageDocument
        ) { url in
          print("Saved to", url) // [URL]
        }
    }
  }
}

import SwiftUI
import UniformTypeIdentifiers

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

  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 {
    // You can replace tiff representation with what you want to export
    return FileWrapper(regularFileWithContents: image.jpegData(compressionQuality: 1)!)
  }
}


struct ContentView: View {
    
    @EnvironmentObject var appContext: AppContext
    
    var body: some View {
        VStack {
            Button(action: {
                appContext.fileSaveDialogShown.toggle()
            }, label: {
                Text("Button")
            })
        }
        .frame(width: 200, height: 200)
    }
}


【问题讨论】:

    标签: swiftui uiimage xcode12


    【解决方案1】:

    您需要将fileExporterdocuments 一起使用,而不是document,后者接受Collection

    这是我在 macOS 上的做法,调整它应该很简单:

    import SwiftUI
    import UniformTypeIdentifiers
    
    struct ImageDocument: FileDocument {
      static var readableContentTypes: [UTType] { [.jpeg, .png, .tiff] }
    
      var image: NSImage
    
      init(image: NSImage?) {
        self.image = image ?? NSImage()
      }
    
      init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,
              let image = NSImage(data: data)
        else {
          throw CocoaError(.fileReadCorruptFile)
        }
        self.image = image
      }
    
      func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        // You can replace tiff representation with what you want to export
        return FileWrapper(regularFileWithContents: image.tiffRepresentation!)
      }
    }
    
    @main
    struct FocalApp: App {
      @StateObject var appContext = AppContext()
    
      var body: some Scene {
        WindowGroup {
          MainView()
            .environmentObject(self.appContext)
            .fileExporter(
              isPresented: $appContext.fileSaveDialogShown,
              documents: [
                ImageDocument(image: NSImage(named: "testimage1")),
                ImageDocument(image: NSImage(named: "testimage2"))
              ],
              contentType: .tiff // Match this to your representation in ImageDocument
            ) { url in
              print("Saved to", url) // [URL]
            }
        }
      }
    }
    
    

    【讨论】:

    • 非常感谢马克斯!您的代码运行良好,但是当用 UIImage 替换 NSImage 时,它​​只导出 1 个图像。我在 iPhone、iPad 和 Catalyst 上试过。全部仅导出 1 张图片...感谢您可能有的任何输入!
    • UIImage 代码在我更新的问题上
    • 我没有在 iOS 上尝试过这个,那里的规则可能会有所不同,尽管文档页面确实声明了 iOS 和 Catalyst 都受支持? developer.apple.com/documentation/swiftui/group/…
    • 是的,应该可以在 iOS 中使用。我测试了很多次,总是在 iOS 上只导出一张图像,而在 MacOS 上全部导出。我向 Apple 提交了代码级支持,如果我找到解决方案会通知您。
    • @ManeManero 您是否碰巧找到了可行的解决方案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 2020-12-23
    • 1970-01-01
    相关资源
    最近更新 更多