|
7 | 7 | // |
8 | 8 |
|
9 | 9 | #import "NSAppearance+PBDarkMode.h" |
| 10 | +#import <objc/runtime.h> |
10 | 11 |
|
11 | 12 | // This definition satisfies the `extern NSString *const` declaration in the |
12 | 13 | // header for all Objective-C callers. The Swift side imports the same value |
13 | 14 | // as a plain Swift String via the bridging header. |
14 | 15 | NSString *const PBEffectiveAppearanceChanged = @"PBEffectiveAppearanceChanged"; |
| 16 | + |
| 17 | +@implementation NSAppearance (PBDarkMode) |
| 18 | + |
| 19 | +- (BOOL)isDarkMode |
| 20 | +{ |
| 21 | + NSAppearanceName bestMatch = [self bestMatchFromAppearancesWithNames:@[NSAppearanceNameDarkAqua, NSAppearanceNameAqua]]; |
| 22 | + return [bestMatch isEqualToString:NSAppearanceNameDarkAqua]; |
| 23 | +} |
| 24 | + |
| 25 | +@end |
| 26 | + |
| 27 | +@implementation NSApplication (PBDarkMode) |
| 28 | + |
| 29 | +- (BOOL)isDarkMode |
| 30 | +{ |
| 31 | + return self.effectiveAppearance.isDarkMode; |
| 32 | +} |
| 33 | + |
| 34 | +static char kAppearanceObservationKey; |
| 35 | + |
| 36 | +- (void)registerObserverForAppearanceChanges:(id)observer |
| 37 | +{ |
| 38 | + // Use traditional KVO addObserver method |
| 39 | + [self addObserver:self |
| 40 | + forKeyPath:@"effectiveAppearance" |
| 41 | + options:NSKeyValueObservingOptionNew |
| 42 | + context:&kAppearanceObservationKey]; |
| 43 | + |
| 44 | + // Store the observer reference |
| 45 | + objc_setAssociatedObject(self, &kAppearanceObservationKey, observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
| 46 | +} |
| 47 | + |
| 48 | +- (void)observeValueForKeyPath:(NSString *)keyPath |
| 49 | + ofObject:(id)object |
| 50 | + change:(NSDictionary *)change |
| 51 | + context:(void *)context |
| 52 | +{ |
| 53 | + if (context == &kAppearanceObservationKey) { |
| 54 | + id observer = objc_getAssociatedObject(self, &kAppearanceObservationKey); |
| 55 | + [[NSNotificationCenter defaultCenter] postNotificationName:PBEffectiveAppearanceChanged |
| 56 | + object:observer]; |
| 57 | + } else { |
| 58 | + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +@end |
| 63 | + |
0 commit comments