【发布时间】:2024-01-31 02:50:01
【问题描述】:
在我的 SwiftUI 应用程序中,我有一个视图供人们编辑书籍的元数据,例如书名和作者。在这个视图中,我有一个显示图书封面图片的图片视图。
struct ImageView: View {
@Binding var book: Book
var body: some View {
// coverFile is the URL to the image file.
let image = NSImage(byReferencing:
book.metadata.coverFile)
Image(nsImage: image)
.aspectRatio(contentMode: .fit)
}
}
当我打开一本书并设置了封面图片并打开元数据编辑器时,图片视图不显示任何内容。元数据编辑器有一个按钮来选择封面图像。当我单击按钮并从文件导入器中选择图像文件时,图像会出现在图像视图中。如果我关闭这本书,重新打开它,然后打开元数据编辑器,图像就会出现在图像视图中。但如果我重新启动应用程序、打开书本并打开元数据编辑器,图像视图将什么也没有显示。
我尝试了各种 NSImage 初始化程序。我尝试从Data 对象和NSBitmapImageRep 构建图像。
extension Book {
func coverImage() -> NSImage {
do {
let data = try Data(contentsOf: metadata.coverFile)
return NSImage(data: data) ?? NSImage()
} catch {
Swift.print("Error reading the image data. Error: \(error)")
}
return NSImage()
}
}
struct ImageView: View {
@Binding var book: Book
var body: some View {
let image = book.coverImage()
Image(nsImage: image)
.aspectRatio(contentMode: .fit)
}
}
但是当我在图像视图中设置断点并检查image 变量时,它要么为零,要么无效。当我检查 coverFile 变量时,它会显示正确的 URL,包括 .png 扩展名。
在这个应用程序的 AppKit 版本中,我有相同的代码来创建 NSImage,并且图像显示在图像视图中。
根据 Apple 的文档,NSImage byReferencing 函数不会尝试从指定的 URL 检索数据或从该数据创建任何图像表示,直到应用程序尝试绘制图像或请求有关它的信息。如何让 SwiftUI 视图触发检索图像数据,使其显示在图像视图中?
更新
我在ImageView 结构中为图像创建了一个计算属性。
var image: NSImage {
do {
let data = try Data(contentsOf: book.metadata.coverFile)
return NSImage(data: data) ?? NSImage()
} catch {
Swift.print("Error creating the image. Error: \(error)")
}
return NSImage()
}
当我运行这段代码时,try Data 调用抛出异常,catch 块运行,并且在 Xcode 的控制台中打印以下错误消息:
创建图像时出错。错误:错误域=NSCocoaErrorDomain Code=257 "无法打开文件“ImageFile”,因为您 无权查看。”
从文件导入器中选择文件可以正确创建数据。我对图像文件所在的文件夹具有读/写权限。
【问题讨论】: