macos - SwiftUI Image 不显示现有文件中的图像
问题描述
在我的 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 代码 = 257 “无法打开文件“ImageFile”,因为您无权查看它。”
从文件导入器中选择一个文件会导致正确创建数据。我对图像文件所在的文件夹具有读/写权限。
解决方案
据我了解,问题归结为懒惰地初始化 NSImage。
您是否尝试过使用 init(contentsOfFile:) 或 init(contentsOf:)?它不会延迟初始化,因此不会导致此问题。
推荐阅读
- python - 如何编写条件使用 django 查询集
- javascript - 在 iOS 的 javascript 中禁用长按振动
- c# - 如果现在没有运行,则使用 C# WinForms 启动一些程序
- spring - 带有参数化 Spring ApplicationContext 配置的 JUnit 参数化测试
- c - 如何在下面的 C 程序中访问来自其他文件的静态变量?
- php - 如何在php中获取数组的长度和值
- python - 合并列(1 月、2 月、3 月等)。
- socket.io - 你如何修复 Socket.io 跨域限制?(我已经尝试过以前的解决方案)
- rust - Rust 中的可变引用传递
- audio - ffmpeg - 复制音频通道但保持相同的质量