Using SF Symbols on iOS 13 and falling back to assets on iOS 12

Is this something that's possible (I'm using storyboards)? I'd like to update my bar button items to SF Symbols (for consistency, since I have some iOS 13 context menus using SF Symbols).

Answered by bbousquet in 389148022

I believe I found the built-in fallback:


- in your storyboard, specify the SF Symbol you want to use (let's say, "gear")

- in your assets catalog, create an asset with the same name ("gear")


On iOS 13, the SF Symbol will be used. On prior versions, it will fallback to using the same named asset from the asset catalog!

How do you call those assets in code ?


Could you use


myAsset = UIImage() // for instance
if #available(iOS 13.0, *) {
     myAsset = // from SFSymbol
} else {
      myAsset = // from asset
}

In code I could create separate UIImage objects (as your code snippet shows). However, my bar button items are all defined in the storyboard.

I do not see how you could do a conditional setup in IB.


Maybe you could create just a container view in IB, then fill it in code.

hi bbousquet,


i think Claude31 is right -- i don't think this can be done in IB.


i'd suggest that you handle this in code, not putting it in IB.


example: i have a a "locked" icon that i would like in the navigation bar (clicking on this button would unlock whatever is the content of the current view controller).


i add a UIBarButtonItem with a SFSymbol icon for a machine running iOS 13, but default it to simple text (you could make this an image, if you like) if i don't have iOS 13.


here's what i use in viewDidLoad():


if isLocked {
  let lockBarButtonItem: UIBarButtonItem
  if #available(iOS 13, *) {
    let image = UIImage(systemName: "lock.fill")
    lockBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(doUnlock))
  } else {
    lockBarButtonItem = UIBarButtonItem(title: "(Locked)", style: .plain, target: self, action: #selector(doUnlock))
  }
  navigationItem.rightBarButtonItems!.append(lockBarButtonItem)
  tableView.allowsSelection = false
}


hope that helps,

DMG

Thank you for the input, guys. I was hoping IB would have a built-in fallback so we don't have to add more lines of code. I'll see which path I take at this point.

Accepted Answer

I believe I found the built-in fallback:


- in your storyboard, specify the SF Symbol you want to use (let's say, "gear")

- in your assets catalog, create an asset with the same name ("gear")


On iOS 13, the SF Symbol will be used. On prior versions, it will fallback to using the same named asset from the asset catalog!

That seems a good idea.


I tested on both XCode 10 and 11.


It compiles and run.


Get the SF icon on iOS13.

But on XCode 10 (iOS12 simulator), the barItem icon does not show.

Did you test on a iOS12 device ?

In Xcode 11 this worked fine. I tried it in both iOS 12 and iOS 13 simulators and, just now, on a 6th gen iPod touch running 12.4.2.


[Xcode 11 does display warnings when building for the iPod touch: SF Symbol '...' is unavailable prior to iOS 13.0]

Adding a fallback image isn't working for me for iOS 14 ('m using a symbol introduced in iOS 15 and I'm getting this warning in a storyboard file). I tried:

  1. Adding a normal image asset with the same name as the symbol in my Asset catalog.
  2. Adding a "Symbol image set" with the same name as a symbol in my Asset catalog.

Neither worked for me. The symbol has dots. like key.radiowaves.forward.fill

Using SF Symbols on iOS 13 and falling back to assets on iOS 12
 
 
Q