You can easily change the various palette color(s) of a system image, for example, when used in an action in a menu:
let conf = UIImage.SymbolConfiguration(paletteColors: [blah])
.applying(UIImage.SymbolConfiguration(pointSize: 50, weight: .medium))
let acn = UIAction(
title: "Blah",
image: UIImage(systemName: "whatever", withConfiguration: conf)
) { [weak self] _ in
guard let self else { return }
yourButtonProcess("bleh")
}
But is it actually possible to change the background color (of the image itself)?
The only way I know to fake it is to build a non-system image, eg https://stackoverflow.com/a/53500161/294884
Is it possible?
In short how to truly change the background color of a system image (for situations where you can't change the bg color of the thing holding it.)
Not wishing to stack up associated questions, but I'm also wondering if you can change the background color of a UIAction (i.e. for example to make "rainbow" color-coded menus).
I think it's important to note that the absolutely key piece of information here is: it turns out SF Symbols in fact have a clear background and that's that. Very interesting. (Sure, obviously you could have one (or more I guess) palette element that happens to be a filling square, so it's "effectively" a background.)
The simple answer is "no, you can't change the background color using UIImage.SymbolConfiguration
". An SF Symbol doesn't have a "background" in the general sense. The only exceptions are the small subset of symbols ending in .square.fill
.
There are various work arounds such as creating a new UIImage
from the original, filling in the background color of the new image. You've posted a link to such a solution.
There is a way to effectively change the answer to "yes", but it requires a bunch of work up front. If you have a limited number of SF Symbols that you wish to apply a background color to, you can use the SF Symbols app to create a set of custom symbols that are each a copy of the original symbol combined with a component, where the chosen component is the background that you want. A likely component for the background would be "square.fill".
Once you create the set of custom symbols you can export each as an SVG. Create a new Asset in your project. For each SVG, add the symbol using "Symbol Image Set" and drag the SVG into the "Symbol SVG" square. Ensure that the "Render As" option is set to "Hierarchical" for each symbol. Ensure each symbol has a useful name (such as "map.square.fill" instead of "Symbol").
Once your custom symbols are in place as assets, your code now becomes something like the following:
let conf = UIImage.SymbolConfiguration(paletteColors: [.systemBackground, .systemRed])
.applying(UIImage.SymbolConfiguration(pointSize: 50, weight: .medium))
let acn = UIAction(
title: "Blah",
image: UIImage(named: "map.square.fill", in: nil, with: conf)
) { [weak self] _ in
guard let self else { return }
yourButtonProcess("bleh")
}
The first palette color is the main symbol color. The second palette color is the background color.
Here are more complete steps for creating and installing a custom symbol with a background using SF Symbols 5.1 and Xcode 15.
map
symbol.custom.map
.square.fill
or one of the other .fill
enclosures since the goal is to add the component as the new symbol's background.map
symbol.custom.map
.square.fill
or one of the other .fill
enclosures since the goal is to add the component as the new symbol's background.UIImage(named:)
variants including UIImage(named:in:with:)
.