如何仅在 SF Symbol 存在的情况下返回图像?

问题描述 投票:0回答:3

我一直在尝试找到一种方法来检查 SF 符号和图像是否存在。
在我遇到的所有答案中,都使用了 nil 合并运算符 (

??
),这需要始终存在的
default
图像。这对我来说不起作用。

我想测试一个图像(或符号)是否存在,如果存在则返回它,否则返回

nil

如何实现这一目标?

重要提示
我正在尝试使用

SwiftUI
Image
来实现多平台应用程序。我试图避免使用
UIImage
NSImage
进行检查。

更新1

注1: 当请求不存在的 SF 符号时(例如,

systemName: [name]
参数中有拼写错误),图像将显示为空白区域。 (用
Label
测试)

以下解决方案经测试无效:
(注:在所有的尝试中,都有一个变量

name: String

解决方案1

let image = Image(systemName: name)
if image {
    return image
} else {
    return nil
}

抛出错误:

无法将“Image”类型的值转换为预期条件类型“Bool”

在以下情况下会抛出完全相同的错误:

let image = Image(name)

解决方案2

if let image = Image(systemName: name) {
    return image
}

抛出错误:

条件绑定的初始化程序必须具有可选类型,而不是“Image”

解决方案3

let image = Image(systemName: name)
if image != nil {
    return image
}

不起作用并给出警告:

将“Image”类型的非可选值与“nil”进行比较始终返回 true

image if-statement swiftui symbols exists
3个回答
2
投票

正如您所发现的,如果名称无法识别,

Image.init(systemName:)
会返回某种占位符图像。

如果你想检测这个名字是否被识别,你可以尝试用它创建一个

UIImage
。如果名称无法识别,
UIImage.init?(systemName:)
返回
nil

let image: Image? = UIImage(systemName: name)
    .map { Image(uiImage: $0) }

上面的

Image
在某些方面可能与使用
Image(systemName:)
创建的图像不同。我不知道。因此,如果出现问题,您可以执行以下操作:

let image: Image? = UIImage(systemName: name)
    .map { _ in Image(systemName: name) }

2
投票

按照 @rob mayoff 的回答,我最终为操作系统创建了案例,然后使用简洁的检查来确定图像是否存在并执行逻辑。

最终,我能够避免在实际检查之外使用

UIImage
NSImage

这是一种非正统且低效的方法,但这就是我的代码最终的样子:

对于自定义图像

#if os(macOS)
if (NSImage(named: name)) != nil {
    //image found, do some logic...
}
#elseif os(iOS)
if (UIImage(named: name)) != nil {
    //image found, do some logic...
}
#endif

对于系统符号

#if os(macOS)
if (NSImage(systemSymbolName: name, accessibilityDescription: "")) != nil {
    //image found, do some logic...
}
#elseif os(iOS)
if (UIImage(systemName: name)) != nil {
    //image found, do some logic...
}
#endif

0
投票

如果您的目的是在视图中显示图像,则仅当提供了图像时,您才可以使用可空图像并使用 if 使用 let 进行测试。下面的示例使用的绑定可能有图像或可能为零:

struct NillableImage: View {
    @State private var nillableImage: Image?

    init(image: Binding<Image?>) {
        self._nillableImage = image
    }

    var body: some View {
        ZStack {
            if let filledImage = nillableImage {
                filledImage
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.