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

Mat*_*der 7 ios swift swiftui

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

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

我的数据模型包含Data正确的可选内容,我将Image其用于View.

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

Image(uiImage: UIImage(data: userService.user.imageData!)!)
Run Code Online (Sandbox Code Playgroud)

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

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

use*_*037 6

方法:

  • 使用控制语句
  • 用于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
    }
}
Run Code Online (Sandbox Code Playgroud)


LuL*_*aGa 6

您有几种选择。我认为最简单的方法是对 Image 进行扩展并定义一个新的初始化程序来满足您的需求:

extension Image {

    public init?(data: Data?) {
        guard let data = data,
            let uiImage = UIImage(data: data) else {
                return nil
        }
        self = Image(uiImage: uiImage)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Image(data: userService.user.imageData)
Run Code Online (Sandbox Code Playgroud)

因为它是它,所以nullable它需要包含在View至少一个 other 中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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Image(data: userService.user.imageData, placeholder: "nameOfPlaceholder")
Run Code Online (Sandbox Code Playgroud)

因为它不是,nullable所以不需要View与至少一个其他一起包含在另一个中View