Issue #749
Some apps want to support alternative app icons in Settings where user can choose to update app icon. Here’s some must do to make it work, as of Xcode 12.2
- In Info.plist, must declare
CFBundleIcons
with bothCFBundlePrimaryIcon
andCFBundleAlternateIcons
- Icons must be in project folder, not Asset Catalog
Here’s how it is done on my app PastePal
Add app icons to project folder
Prepare icons, like Icon1, Icon2 with 2 variants for 2x and 3x. These need to be added to project folder. When I add these to Asset Catalog it does not update app icon. I usually add a new folder in project like Resource/AlternateAppIcons
The default 1x size for iPhone icon size from iOS 7 to iOS 14 is 60px.
- Icon1@2x.png : 120x120
- Icon1@3x.png: 180x180
Declare in Info.plist
Although declaring CFBundlePrimaryIcon
seems unnecessary, I find that without this it does not work. I use AppIcon60x60
as the compiled one from Asset Catalog for our main AppIcon
For UIPrerenderedIcon
, a boolean value indicating whether the app’s icon already contains a shine effect. We set to false to allow iOS to apply round and glossy effect to our icon.
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon60x60</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AppIconPride1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIconPride1</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>AppIconPride2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIconPride2</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
</dict>
Asset Catalog
Since we’re using Asset Catalog, if we simply use UIImage with named, it will load by default in Asset Catalog, unless we manually specify bundle path. For simple demo, we can just copy our images again to Asset Catalog so we can show in the app
I usually have an enum of AlternateAppIcon
so I can display in a grid and let user choose
enum AlternateAppIcon: String, CaseIterable, Identifiable {
var id: AlternateAppIcon { self }
case main = "Main"
case pride1 = "Pride1"
case pride2 = "Pride2"
}
func onChange(_ icon: AlternateAppIcon) {
guard UIApplication.shared.supportsAlternateIcons else { return }
switch icon {
case .main:
UIApplication.shared.setAlternateIconName(nil)
default:
UIApplication.shared.setAlternateIconName(icon.name)
}
}
Change app icon for iPad
So far we’re only talk about iPhone. To support iPad, we need to specify iPad versions in Info.plist with CFBundleIcons~ipad
- CFBundleIcons
- CFBundleAlternateIcons
- Icon Name
- CFBundleIconFiles
- CFBundleIcons~ipad
- CFBundleAlternateIcons
- Icon Name
- CFBundleIconFiles
Also notice the size for icons on iPad