Этот код показывает, как добавить альтернативный значок на основе темы iOS и ваш набор настроек. Я также добавил accent1Icon и accent2Icon в качестве примеров.
В вашем файле Settings.bundle вам нужно добавить элемент Multi Value - App к элементам предпочтений (Apple требует, чтобы пользователи могли менять тему, даже если вы автоматически устанавливаете его, основываясь на их iOS настройках):
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Values</key>
<array>
<string>0</string>
<string>1</string>
<string>2</string>
<string>3</string>
<string>4</string>
</array>
<key>Title</key>
<string>App Icon Theme</string>
<key>Key</key>
<string>app_icon_theme</string>
<key>DefaultValue</key>
<string>0</string>
<key>Titles</key>
<array>
<string>Use iOS Theme</string>
<string>Dark Theme</string>
<string>Light Theme</string>
<string>Accent1 Theme</string>
<string>Accent2 Theme</string>
</array>
</dict>
Создайте класс, минимально имеющий вашу настройку app_icon_theme:
class SettingsBundleHelper {
struct SettingsBundleKeys {
static let AppIconThemeKey = "app_icon_theme"
}
}
Добавьте это в ваш info.plist:
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>darkIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>name-of-dark-icon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>accent1Icon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>name-of-accent1-icon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>accent2Icon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>name-of-accent2-icon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
Создайте в своем проекте папку с именем Alternate Icons
и сохраните в ней name-of-dark-icon@2x.png и name-of-dark-icon@3x.png.
YourProject
|
+-- Alternate Icons (folder)
|
+-- name-of-dark-icon@2x.png
+-- name-of-dark-icon@3x.png
+-- name-of-accent1-icon@2x.png
+-- name-of-accent1-icon@3x.png
+-- name-of-accent2-icon@2x.png
+-- name-of-accent2-icon@3x.png
Вы можете запустить код changeIcon в приложении AppDelegate applicationDidBecomeActive (или в другом месте). Если вы решите запустить его там, вам нужно добавить его в файл AppDelegate:
enum AppIconTheme: String {
case UseiOSTheme = "0"
case DarkTheme = "1"
case LightTheme = "2"
case Accent1Theme = "3"
case Accent2Theme = "4"
}
func applicationDidBecomeActive(_ application: UIApplication) {
// update icon if dark mode
if #available(iOS 12.0, *) {
var theme = AppIconTheme.UseiOSTheme
if let iconTheme = UserDefaults.standard.string(forKey: SettingsBundleHelper.SettingsBundleKeys.AppIconThemeKey) {
if let themeSettings = AppIconTheme(rawValue: iconTheme) {
theme = themeSettings
}
}
print(theme as Any)
switch (theme) {
case .UseiOSTheme:
if UIApplication.shared.windows[0].rootViewController?.traitCollection.userInterfaceStyle == .dark {
self.changeIcon(to: "darkIcon")
} else {
self.changeIcon(to: nil)
}
case .LightTheme:
self.changeIcon(to: nil)
case .DarkTheme:
self.changeIcon(to: "darkIcon")
case .Accent1Theme:
self.changeIcon(to: "accent1Icon")
case .Accent2Theme:
self.changeIcon(to: "accent2Icon")
}
} else {
// Fallback on earlier versions
var theme = AppIconTheme.UseiOSTheme
if let iconTheme = UserDefaults.standard.string(forKey: SettingsBundleHelper.SettingsBundleKeys.AppIconThemeKey) {
theme = AppIconTheme(rawValue: iconTheme)!
}
print(theme as Any)
switch (theme) {
case .UseiOSTheme:
self.changeIcon(to: nil)
case .LightTheme:
self.changeIcon(to: nil)
case .DarkTheme:
self.changeIcon(to: "darkIcon")
case .Accent1Theme:
self.changeIcon(to: "accent1Icon")
case .Accent2Theme:
self.changeIcon(to: "accent2Icon")
}
}
}
func changeIcon(to name: String?) {
//Check if the app supports alternating icons
guard UIApplication.shared.supportsAlternateIcons else {
return;
}
if UIApplication.shared.alternateIconName != name {
//Change the icon to a specific image with given name
// if name is nil, the app icon will be the default app icon
UIApplication.shared.setAlternateIconName(name) { (error) in
//After app icon changed, print our error or success message
if let error = error {
print("App icon failed to due to \(error.localizedDescription)")
} else {
print("App icon changed successfully.")
}
}
}
}
Вот документация от Apple по setAlternativeIcon: https://developer.apple.com/documentation/uikit/uiapplication/2806818-setalternateiconname