SwiftUI - 解包可选图像数据以基于 UIImage(data) 创建图像



我找到了这个链接,一些答案说我们可以解决两个任务:

  • 根据需要显示视图元素
  • 或者,如果找到 nil,则显示默认值

我有数据模型,它正确包含可选Data,我将其用于View上的Image元素。

目前,由于我还没有找到解决此问题的方法并使用此标志!这是不安全的:

Image(uiImage: UIImage(data: userService.user.imageData!)!)

当然,我不能保证它,我不应该使用它,但需要帮助如何解开它。

作为一种快速解决方法,我可以将此图像数据属性设置为非可选属性,然后从本地文件加载一些数据,但即便如此,我仍然在这里还有一个强制解包UIImage(data

您有几个可用的选项。我认为最直接的是在 Image 上做一个扩展,并定义一个新的初始化器来满足你的需求:

extension Image {
public init?(data: Data?) {
guard let data = data,
let uiImage = UIImage(data: data) else {
return nil
}
self = Image(uiImage: uiImage)
}
}

然后你可以像这样简单地使用它:

Image(data: userService.user.imageData)

由于它是nullable因此需要包含在另一个View中,至少有一个其他View

如果要提供一个占位符来代替丢失的图像,可以使用如下所示的扩展名:

extension Image {
public init(data: Data?, placeholder: String) {
guard let data = data,
let uiImage = UIImage(data: data) else {
self = Image(placeholder)
return
}
self = Image(uiImage: uiImage)
}
}

然后你可以像这样简单地使用它:

Image(data: userService.user.imageData, placeholder: "nameOfPlaceholder")

由于它不是nullable因此不需要包含在具有至少一个其他View的另一个View中。

方法:

  • 使用控制语句
  • 使用AnyView擦除文字

AnyView原因

  • 您需要擦除该类型,以便您的视图始终返回相同的视图类型,而不管它采用哪种执行路径(无论if语句是否满足)。
  • 这样它无论如何都会返回AnyView,并将满足体型(some View)

例:

  • 如果数据是有效的图像数据,则将显示图像
  • 如果不是,则显示一个空视图

注:您可以显示任何其他视图,而不是空视图。

法典:

import SwiftUI
class Model : ObservableObject {
var data : Data?
init(data: Data?) {
self.data = data
}
}
struct ContentView: View {
@ObservedObject var model : Model
var body: some View {
let view : AnyView
if let data = model.data,
let uiimage = UIImage(data: data) {
view = AnyView(Image(uiImage: uiimage))
}
else {
view = AnyView(EmptyView()) //You could have view = AnyView(Text("no image found"))
}
return view
}
}

以下变体简单且安全(如果您需要始终在视图层次结构中具有 Image),因为UIImage(data: Data())总是创建有效的空图像。

Image(uiImage: UIImage(data: userService.user.imageData ?? Data())!)

最新更新