Check if SF Symbol exists Swift
Asked Answered
S

3

6

I want to display a SwiftUI Image with a number. I might do so like this:

let number = 13
Image(systemName: "\(number).square.fill")

However, not every number has an SF Symbol — what if I wanted to display 134.square.fill but discovered that there isn't one, crashing the app?

How can I check if an SF Symbol exists without crashing the app?

Stutsman answered 4/8, 2019 at 10:24 Comment(1)
I don't know if this was different before, but my apps won't crash if the symbol image does not exist. There will be simply no image, just blank.Siren
K
7

The following code will show the question mark symbol, if one for the number does not exist. But you can adapt it to do anything.

struct ContentView: View {
    var body: some View {
        let number = 144

        return VStack {
            Image(uiImage: UIImage(systemName: "\(number).square.fill") ?? UIImage(systemName: "questionmark.square.fill")!)
        }
    }
}
Kristiankristiansand answered 4/8, 2019 at 10:37 Comment(4)
UIImage(systemName: "\(number).square.fill") ?? UIImage(systemName: "questionmark.square.fill")!Unpolitic
@LeoDabus Yeap, I updated the answer to include your improvement. Cheers.Kristiankristiansand
you could use my enum, which supports use of Image with SFSymbols as an enum: github.com/luckychris/SFSymbols. Then you know at compile time wether it exists and you get autocompletion for free.Strikebreaker
When you use Image(uiImage: UIImage(....)) you lose the ability to apply attributes like foregroundColor and font. If you want to keep those, then you should check if UIImage(systemName: ...) returns nil or not, then load it directly using Image(systemName: ...) I don't personally like this loading the image twice but it seems you can't have it both ways.Incompetence
B
4

After being in this situation myself, @kontiki’s answer really gave me a head start, but in his solution, the modifiers we apply to the image won’t work, so this is my approach:

We create a function that returns a String instead of an Image:

func safeSystemImage(_ systemName: String) -> String {
    let image = "\(systemName).square.fill"
    
    return UIImage(systemName: image) != nil ? image : "" // ← The image you want in case it doesn't exist.
}

Usage:

Image(systemName: safeSystemImage(yourImage))

This way we can change it’s color, size, etc…

Botryoidal answered 30/1, 2022 at 5:41 Comment(0)
B
-2

Use an API Availability Check for each specific symbol.

For example:

if #available(iOS 17.0, *) {
    Image(systemName: "circle.dotted.and.circle")
} else {
    Image(systemName: "network")
}

Use the SF Symbols app to determine the platforms for which a symbol is available. Select a symbol in the SF Symbols app. Choose View > Inspectors > Show Info Inspector (⌥⌘1). Then see the Availability heading.

Brunk answered 7/11, 2023 at 19:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.