I've been trying to find a way to check if SF Symbols and Images exist.
In all of the answers I've come across, the nil coalescing operator (??
) is used, which requires a default
image that always exists. This doesn't work in my case.
I would like to test if an image (or a symbol) exists and then return it if it exists, otherwise return nil
.
How can this be achieved?
IMPORTANT NOTE
I am trying to achieve this using SwiftUI
's Image
for a multiplatform application. I am trying to avoid using UIImage
or NSImage
to do my checks.
UPDATE 1
Note 1:
When requesting an SF Symbol that does not exist (for example, there was a typo in the systemName: [name]
parameter), the image appears as an empty area. (Tested with Label
)
The following solutions have been tested and are ineffective:
(Note: in all of the attemps, there are is a variable name: String
)
let image = Image(systemName: name)
if image {
return image
} else {
return nil
}
Throws the error:
Cannot convert value of type 'Image' to expected condition type 'Bool'
It throws the exact same error when: let image = Image(name)
if let image = Image(systemName: name) {
return image
}
Throws the error:
Initializer for conditional binding must have Optional type, not 'Image'
let image = Image(systemName: name)
if image != nil {
return image
}
Does not work and gives the warning:
Comparing non-optional value of type 'Image' to 'nil' always returns true
As you have discovered, Image.init(systemName:)
returns some sort of placeholder image if the name isn't recognized.
If you want to detect whether the name is recognized, you can try creating a UIImage
with it. UIImage.init?(systemName:)
returns nil
if the name isn't recognized.
let image: Image? = UIImage(systemName: name)
.map { Image(uiImage: $0) }
The above Image
might behave differently in some ways than an image created with Image(systemName:)
. I'm not sure. So you can do the following instead if that is a problem:
let image: Image? = UIImage(systemName: name)
.map { _ in Image(systemName: name) }