UIImage(named:) with period loads wrong image (e.g. for SFSymbols)

185 views Asked by At

I want an easy way to load SFSymbol images with configuration, if possible. Else just load the image normally. So I have this extension and I have all SFSymbols I need in in my assetcatalog with the same name as the symbol (in this case I have "circle" and "circle.fill").

However, in iOS 12 this gives me "circle"!

I assume what's happening is that it counts the dot/period (i.e. circle . fill) as a file extension and assumes the extension is wrong so just grab the circle image with the 'other extension'. Even tho it's not. Is there an easy fix for this? Is this intended?

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let imageView = UIImageView(frame: CGRect(x: 30, y: 30, width: 50, height: 50))
        imageView.image = UIImage.image(sfsymbolName: "circle.fill")
        view.addSubview(imageView)
    }
}

extension UIImage {
    static func image(sfsymbolName: String, config: Any? = nil) -> UIImage? {
        if #available(iOS 13.0, *), let sfImage = UIImage(systemName: sfsymbolName, withConfiguration: config as? UIImage.Configuration) {
            return sfImage
        } else {
            return UIImage(named: sfsymbolName)
        }
    }
}
1

There are 1 answers

0
thisIsTheFoxe On

As mentioned in @matt's comment the probably best solution is to just not have images in you asset catalog with a dot (.). Instead use a different character which you can replace at runtime. Just make sure that that character also also doesn't appear in any SFSymbol name (e.g. an underscore _). Then you can load the image like this:

let image = loadImage(named: "circle_fill")

func loadImage(named imageName: String) -> UIImage? {
    let sfSymbolName = imageName.replacingOccurrences(of: "_", with: ".")
    if #available(iOS 13.0, *), let img = UIImage(systemName: sfSymbolName)
        return img
    } else {
        return UIImage(named: imageName)
    }
}

With the catalog file structure looking like:

|Assets.xcassets
|--circle.imageset
|----...
|--circle_fill.imageset
|----...