问题描述
这是对该线程的跟进: SwiftUI 2.0: export images with .fileExporter modifier
目标:在 SwiftUI 中导出一组图片
我做了什么: 我正在使用 .fileExporter 修饰符和 FileDocument 结构。 也对其他方法开放,例如 .例如 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)
}
}
解决方法
您需要将 fileExporter
与 documents
一起使用,而不是 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]
}
}
}
}