Skip to content

Instantly share code, notes, and snippets.

@insidegui
Last active March 14, 2026 19:28
Show Gist options
  • Select an option

  • Save insidegui/686ae55087542b430be976918418d129 to your computer and use it in GitHub Desktop.

Select an option

Save insidegui/686ae55087542b430be976918418d129 to your computer and use it in GitHub Desktop.
A SwiftUI view that renders a Mac app's icon in the current appearance, respecting Liquid Glass customizations
import SwiftUI
#if canImport(WidgetKit)
import WidgetKit
#endif
/// Displays the app's icon in the current appearance (light, dark, clear, etc).
///
/// - note: The appearance of the icon will only reflect what's currently selected in System Settings,
/// it will not update in SwiftUI previews or if the app is overriding its own appearance.
public struct AppIconView: View {
public var size: CGFloat
@State private var provider = _Provider()
public init(size: CGFloat = 128) {
self.size = size
}
@Observable
final class _Provider {
private(set) var icon = NSImage.appIcon
@ObservationIgnored private var iconAppearanceObservation: Any?
@ObservationIgnored private var appAppearanceObservation: NSKeyValueObservation?
init() {
/// Refresh icon image when configuration changes.
iconAppearanceObservation = NSWorkspace.shared.notificationCenter.addObserver(forName: .iconAppearanceConfigurationDidChange, object: nil, queue: .main) { [weak self] _ in
self?.didChange()
}
/// Refresh icon image when app appearance changes.
appAppearanceObservation = NSApplication.shared.observe(\.effectiveAppearance) { [weak self] app, _ in
self?.didChange()
}
}
private func didChange() {
icon = NSImage.appIcon
}
deinit {
if let iconAppearanceObservation {
NSWorkspace.shared.notificationCenter.removeObserver(iconAppearanceObservation)
}
}
}
private var image: NSImage {
let icon = provider.icon
icon.size = NSSize(width: size, height: size)
return icon
}
public var body: some View {
Image(nsImage: image)
.resizable()
#if canImport(WidgetKit)
/// Ensure icon renders correctly in tinted widgets.
.widgetAccentedRenderingMode(.fullColor)
#endif
.frame(width: size, height: size)
}
}
extension NSImage {
/// The main bundle app icon in the current system style.
static var appIcon: NSImage { NSWorkspace.shared.icon(forFile: Bundle.main.bundlePath) }
}
private extension Notification.Name {
static let iconAppearanceConfigurationDidChange = Notification.Name("NSWorkspaceIconAppearanceConfigurationDidChangeNotification")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment