1. 程式人生 > >macOS 開發 - NSWindow 自定義樣式

macOS 開發 - NSWindow 自定義樣式


零:整體結構

視窗物件包括titleBar,contentView內容檢視,contentBoder底部邊框區。

titleBar上面包括控制按鈕,標題。

視窗的組成


一、設定標題

[self.window setTitle:@"我的 App 標題"];


二、設定標題欄圖示

先將 png 格式圖片拖到Assets 中,我的圖片名為’swift.png’
配置程式碼如下:


    NSImage *image = [NSImage imageNamed:@"swift"];
    [[self.window standardWindowButton:NSWindowDocumentIconButton] setImage:image];

三、設定視窗背景顏色

方法1:window.backgroundColor

- (void)setWindowBKColor {
    [self.window setOpaque:NO
]; [self.window setBackgroundColor:[NSColor cyanColor]]; }

方法2:window.contentView.layer.backgroundColor


    self.window.contentView.layer.backgroundColor = [NSColor cyanColor].CGColor;
    self.window.contentView.wantsLayer = YES;

同時設定


    self.window.contentView.layer.backgroundColor = [NSColor redColor].CGColor;
    self.window.contentView.wantsLayer = YES;

    self.window.backgroundColor = [NSColor cyanColor];

視窗顯示為紅色,不論設定順序。


四、設定 Content Border

預設是none 不顯示出來.
需要顯示的話可以選擇 Small/Large Bottom Border 其他選項
這裡我還不知道怎麼用程式碼控制,會的可以告訴我。

Content Border 配置


五、設定為點選背景可以移動視窗

  • 如果隱藏了標題欄,點選標題欄位置,仍然可以拖動視窗。但是使用者不知道標題欄的位置,所以需要設定點選背景也可以移動。

[self.window setMovableByWindowBackground:YES];


六、隱藏titlebar

方法1:xib上設定

選中window,取消勾選titleBar。
程式碼中可以通過 window.hasTitleBar 來了解titleBar是否存在,但是 hasTitleBar 屬性為只讀,所以不能通過程式碼設定 hasTitleBar。

這裡寫圖片描述

新增顏色看看效果
連左上角 關閉、放大等選項也消失
這裡寫圖片描述


方法2:程式碼設定

self.window.titlebarAppearsTransparent=YES;
self.window.titleVisibility = NSWindowTitleHidden;

隱藏titlebar

設定window.contentView 的顏色後,顯示效果如下:
- 可以看到關閉、放大選項,titleBar 只是被隱藏,不代表不存在。

隱藏titlebar


七、titleBar和 contentView 融合到一起

xib:在Main.storyboard選中Window,勾選屬性Full Size Content View

程式碼:
self.window.styleMask = self.window.styleMask | NSWindowStyleMaskFullSizeContentView;

  • 不隱藏titleBar

titleBar和contentView融合

  • 隱藏titleBar

titleBar和contentView融合-隱藏titleBar


八、自定義titleBar

參考 tongwei117:mac 自定義titlebar
https://blog.csdn.net/tongwei117/article/details/71480693

我的 demo 地址:https://gitee.com/melissashu/MacCustomTitleBar
喜歡的,拖到頁面最下端給個打賞哦:)


原理:隱藏系統自帶的titlebar, 繼承NSView自己繪製一個titlebar, 在其上新增相應的關閉,最小化,最大化按鈕,可以自定義調節顏色,隱藏,顯示,高度,以及新增相應的其它控制元件。

核心程式碼:

 self.window.titlebarAppearsTransparent = YES;
    self.window.titleVisibility = NSWindowTitleHidden;
    [self.window setStyleMask:[self.window styleMask] | NSWindowStyleMaskFullSizeContentView];  


    self.window.contentViewController = [[MSCBViewController alloc]init];

需要在 MSCBViewController 上新增 customView 和 相應的關閉等按鈕。


如果不指定 window.contentViewController,而是直接使用 contentView 新增,左上角按鈕還會存在。

NSView *msTitleBar = [[NSView alloc]initWithFrame:NSMakeRect(0, titleBarY, self.window.frame.size.width, titleBarH)];

msTitleBar.wantsLayer = YES; //需要先設定這個,再設定顏色,否則顏色無效
    msTitleBar.layer.backgroundColor = [NSColor redColor].CGColor;
[self.window.contentView addSubview:msTitleBar];

九、常用屬性、系統樣式

常用的建立程式碼:

NSRect frame = CGRectMake(0, 0, 200, 200);
NSUInteger style =  NSTitledWindowMask | NSClosableWindowMask |NSMiniaturizableWindowMask | NSResizableWindowMask;
NSWindow *window = [NSWindow alloc]initWithContentRect:frame styleMask:style backing:NSBackingStoreBuffered defer:YES];
window.title = @"New Create Window";
[window makeKeyAndOrderFront:self];

1、styleMask: 按位表示的視窗風格引數

enum {
   NSBorderlessWindowMask = 0, //沒有頂部titilebar邊框
   NSTitledWindowMask = 1 << 0, //有頂部titilebar邊框
   NSClosableWindowMask = 1 << 1,//帶有關閉按鈕
   NSMiniaturizableWindowMask = 1 << 2,//帶有最小化按鈕
   NSResizableWindowMask = 1 << 3,//恢復按鈕
   NSTexturedBackgroundWindowMask = 1 << 8 //帶紋理背景的window
};

2、backing:視窗繪製的快取模式

enum {
   NSBackingStoreRetained       = 0,// 相容老系統引數,基本很少用到
   NSBackingStoreNonretained  = 1,//不快取直接繪製
   NSBackingStoreBuffered        = 2//快取繪製
};

3、defer:表示延遲建立還是立即建立

4、NSWindowStyleMask

typedef NS_OPTIONS(NSUInteger, NSWindowStyleMask) {
    NSWindowStyleMaskBorderless = 0,
    NSWindowStyleMaskTitled = 1 << 0,//顯示標題
    NSWindowStyleMaskClosable = 1 << 1,//可關閉,如果不加,則關閉按鈕處顯示一個灰色按鈕,不可點選
    NSWindowStyleMaskMiniaturizable = 1 << 2, //可最小化
    NSWindowStyleMaskResizable  = 1 << 3,//可調整尺寸,即拉伸

    NSWindowStyleMaskTexturedBackground = 1 << 8,//北京味文字,標題欄沒有邊框線。如果需要線,要使用 NSUnifiedTitleAndToolbarWindowMask

    NSWindowStyleMaskUnifiedTitleAndToolbar = 1 << 12, //標題欄和toolBar 下有統一的分割線

    NSWindowStyleMaskFullScreen NS_ENUM_AVAILABLE_MAC(10_7) = 1 << 14,//全屏顯示

    NSWindowStyleMaskFullSizeContentView NS_ENUM_AVAILABLE_MAC(10_10) = 1 << 15,//contentView會充滿整個視窗。

    /* 下面樣式只適用於NSPanel及其子類 */
    NSWindowStyleMaskUtilityWindow          = 1 << 4,
    NSWindowStyleMaskDocModalWindow         = 1 << 6,
    NSWindowStyleMaskNonactivatingPanel     = 1 << 7, 
    NSWindowStyleMaskHUDWindow NS_ENUM_AVAILABLE_MAC(10_6) = 1 << 13 //用於頭部顯示的panel 
};

優秀作品:


參考資料:
劍指人心: http://www.macdev.io/ebook/window.html