116 lines
2.8 KiB
Swift
116 lines
2.8 KiB
Swift
import Combine
|
|
import SwiftUI
|
|
|
|
class AppIconHelper: ObservableObject {
|
|
|
|
static let shared = AppIconHelper()
|
|
|
|
@Published var isDarkMode: Bool = false
|
|
|
|
private init() {
|
|
}
|
|
|
|
func updateDarkModeStatus(for colorScheme: ColorScheme) {
|
|
isDarkMode = colorScheme == .dark
|
|
}
|
|
|
|
func isInDarkMode(for colorScheme: ColorScheme) -> Bool {
|
|
return colorScheme == .dark
|
|
}
|
|
|
|
var supportsModernIconFeatures: Bool {
|
|
if #available(iOS 17.0, *) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func getRecommendedIconVariant(for colorScheme: ColorScheme) -> IconVariant {
|
|
if colorScheme == .dark {
|
|
return .dark
|
|
}
|
|
return .standard
|
|
}
|
|
|
|
var supportsAlternateIcons: Bool {
|
|
if #available(iOS 10.3, *) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
enum IconVariant {
|
|
case standard
|
|
case dark
|
|
case tinted
|
|
|
|
var description: String {
|
|
switch self {
|
|
case .standard:
|
|
return "Standard"
|
|
case .dark:
|
|
return "Dark Mode"
|
|
case .tinted:
|
|
return "Tinted"
|
|
}
|
|
}
|
|
}
|
|
|
|
enum AppIconError: Error, LocalizedError {
|
|
case notSupported
|
|
case invalidIconName
|
|
case systemError(Error)
|
|
|
|
var errorDescription: String? {
|
|
switch self {
|
|
case .notSupported:
|
|
return "Alternate icons are not supported on this device"
|
|
case .invalidIconName:
|
|
return "The specified icon name is invalid"
|
|
case .systemError(let error):
|
|
return "System error: \(error.localizedDescription)"
|
|
}
|
|
}
|
|
}
|
|
|
|
struct IconAppearanceModifier: ViewModifier {
|
|
@Environment(\.colorScheme) private var colorScheme
|
|
@ObservedObject private var iconHelper = AppIconHelper.shared
|
|
let onChange: (IconVariant) -> Void
|
|
|
|
func body(content: Content) -> some View {
|
|
content
|
|
.onChange(of: colorScheme) {
|
|
iconHelper.updateDarkModeStatus(for: colorScheme)
|
|
onChange(iconHelper.getRecommendedIconVariant(for: colorScheme))
|
|
}
|
|
.onAppear {
|
|
iconHelper.updateDarkModeStatus(for: colorScheme)
|
|
onChange(iconHelper.getRecommendedIconVariant(for: colorScheme))
|
|
}
|
|
}
|
|
}
|
|
|
|
extension View {
|
|
func onIconAppearanceChange(_ onChange: @escaping (IconVariant) -> Void) -> some View {
|
|
modifier(IconAppearanceModifier(onChange: onChange))
|
|
}
|
|
}
|
|
|
|
#if DEBUG
|
|
extension AppIconHelper {
|
|
static var preview: AppIconHelper {
|
|
let helper = AppIconHelper()
|
|
helper.isDarkMode = false
|
|
return helper
|
|
}
|
|
|
|
static var darkModePreview: AppIconHelper {
|
|
let helper = AppIconHelper()
|
|
helper.isDarkMode = true
|
|
return helper
|
|
}
|
|
}
|
|
#endif
|