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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章