5

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?

Div
  • 1,363
  • 2
  • 11
  • 28

2 Answers2

5

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")!)
        }
    }
}
kontiki
  • 37,663
  • 13
  • 111
  • 125
  • `UIImage(systemName: "\(number).square.fill") ?? UIImage(systemName: "questionmark.square.fill")!` – Leo Dabus Aug 04 '19 at 12:23
  • 1
    @LeoDabus Yeap, I updated the answer to include your improvement. Cheers. – kontiki Aug 04 '19 at 12:44
  • you could use my enum, which supports use of Image with SFSymbols as an enum: https://github.com/luckychris/SFSymbols. Then you know at compile time wether it exists and you get autocompletion for free. – Chris Dec 04 '19 at 13:50
  • 1
    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. – P. Ent Aug 02 '21 at 13:54
2

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…

LeonardoXUI
  • 411
  • 3
  • 10