簡體   English   中英

在 macOS (objective-c) 上以編程方式更新模式更改(暗模式、亮模式)設置 colors

[英]Updating programmatically set colors on Mode change (dark mode, light mode) on macOS (objective-c)

我在 macOS 上,objective-c,而不是 iOS。XCode 12。

在很多視圖中,我這樣設置 colors:

self.menuIconBar.wantsLayer = YES;
self.menuIconBar.layer.backgroundColor = [NSColor colorNamed:@"color_gradient_right"].CGColor;

每當用戶更改外觀時,例如更改為暗模式,我希望我的 colors 會根據資產設置進行更改:

在此處輸入圖像描述

不幸的是,沒有任何反應。 但是:在 IB 中應用的相同顏色直接按預期變化。 我仍然需要他們以編程方式改變。

然后我試着掛上通知:

[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(appleInterfaceThemeChangedNotification:) name:@"AppleInterfaceThemeChangedNotification" object:nil];

我收到了通知,但是當我再次調用與上面相同的代碼時,仍然加載了錯誤的顏色。

self.menuIconBar.layer.backgroundColor = [NSColor colorNamed:@"color_gradient_right"].CGColor;

任何幫助表示贊賞

以下示例將根據系統偏好設置中的外觀設置更改自定義視圖的背景顏色。 它可以通過創建一個 objc 項目、刪除預先存在的 App Delegate 並將“main.m”中的代碼替換為以下代碼來在 Xcode 中運行:

#import <Cocoa/Cocoa.h>

@interface CustomView : NSView
@end

@implementation CustomView

- (id)initWithFrame:(NSRect)frameRect {
 if ((self = [super initWithFrame:frameRect]) != nil) {
 // Add initialization code here
 }
 return self;
}
 
- (void)drawRect:(NSRect)rect {
}

- (void)viewDidChangeEffectiveAppearance {
 NSLog (@"appearance did change.");
 NSAppearance *changedAppearance = NSApp.effectiveAppearance;
 NSAppearanceName newAppearance = [changedAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
 NSLog (@"new appearance name = %@", newAppearance);
  if([newAppearance isEqualToString:NSAppearanceNameDarkAqua]){
    [[self layer] setBackgroundColor:CGColorCreateGenericRGB( 1.0, 0.0, 0.0, 1.0 )];
  } else {
    [[self layer] setBackgroundColor:CGColorCreateGenericRGB( 0.0, 0.0, 1.0, 1.0 )];
  }
}

 // Use this if you want 0,0 (origin) to be top, left
 // Otherwise origin will be at bottom, left (Unflipped)
-(BOOL)isFlipped {
  return YES;
}
@end
 
@interface AppDelegate : NSObject <NSApplicationDelegate> {
 NSWindow *window;
}

 - (void) buildMenu;
 - (void) buildWindow;
@end
 
@implementation AppDelegate
   
- (void) buildMenu {
 NSMenu *menubar = [NSMenu new];
 NSMenuItem *menuBarItem = [NSMenuItem new];
 [menubar addItem:menuBarItem];
 [NSApp setMainMenu:menubar];
 NSMenu *appMenu = [NSMenu new];
 NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
 action:@selector(terminate:) keyEquivalent:@"q"];
 [appMenu addItem:quitMenuItem];
 [menuBarItem setSubmenu:appMenu];
}
 
- (void) buildWindow {
 #define _wndW  600
 #define _wndH  550
 
 window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )
 styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable
 backing: NSBackingStoreBuffered defer: NO];
 
 [window center];
 [window setTitle: @"Test window"];
 [window makeKeyAndOrderFront: nil];
 
 // **** CustomView **** //
 CustomView *view = [[CustomView alloc]initWithFrame:NSMakeRect( 20, 60, _wndW - 40, _wndH - 80 )];
 [view setWantsLayer:YES];
 [[view layer] setBackgroundColor:CGColorCreateGenericRGB( 0.0, 0.0, 1.0, 1.0 )];
 [[window contentView] addSubview:view];
 
 // **** Quit btn **** //
 NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 10, 40, 40 )];
 [quitBtn setBezelStyle:NSBezelStyleCircular ];
 [quitBtn setTitle: @"Q" ];
 [quitBtn setAction:@selector(terminate:)];
 [[window contentView] addSubview: quitBtn];
}
 
- (void) applicationWillFinishLaunching: (NSNotification *)notification {
 [self buildMenu];
 [self buildWindow];
}
 
- (void) applicationDidFinishLaunching: (NSNotification *)notification {
}
@end
 
int main() {
 NSApplication *application = [NSApplication sharedApplication];
 AppDelegate *appDelegate = [[AppDelegate alloc] init];
 [application setDelegate:appDelegate];
 [application run];
 return 0;
}

這在我的NSView子類中對我有用:

- (void)awakeFromNib {
    self.wantsLayer             = YES;// might be unnecessary
}

- (void)viewDidChangeEffectiveAppearance {
    self.needsDisplay           = YES;
}

- (void)updateLayer {
    self.layer.backgroundColor  = NSColor.unemphasizedSelectedContentBackgroundColor.CGColor;
}

從 macOS 11 開始,應該使用performAsCurrentDrawingAppearance : 實例方法,並在給定塊的外觀更改后添加要應用的任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM