我找到了这个链接,一些答案说我们可以解决两个任务:
- 根据需要显示视图元素
- 或者,如果找到 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())!)