macOS 開發 - NSWindow 自定義樣式
- 零:整體結構
- 一、設定標題
- 二、設定標題欄圖示
- 三、設定視窗背景顏色
- 四、設定 Content Border
- 五、設定為點選背景可以移動視窗
- 六、隱藏titlebar
- 七、titleBar和 contentView 融合到一起
- 八、自定義titleBar
- 九、常用屬性、系統樣式
零:整體結構
視窗物件包括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 其他選項
這裡我還不知道怎麼用程式碼控制,會的可以告訴我。
五、設定為點選背景可以移動視窗
- 如果隱藏了標題欄,點選標題欄位置,仍然可以拖動視窗。但是使用者不知道標題欄的位置,所以需要設定點選背景也可以移動。
[self.window setMovableByWindowBackground:YES];
六、隱藏titlebar
方法1:xib上設定
選中window,取消勾選titleBar。
程式碼中可以通過 window.hasTitleBar 來了解titleBar是否存在,但是 hasTitleBar 屬性為只讀,所以不能通過程式碼設定 hasTitleBar。
新增顏色看看效果
連左上角 關閉、放大等選項也消失
方法2:程式碼設定
self.window.titlebarAppearsTransparent=YES;
self.window.titleVisibility = NSWindowTitleHidden;
設定window.contentView
的顏色後,顯示效果如下:
- 可以看到關閉、放大選項,titleBar 只是被隱藏,不代表不存在。
七、titleBar和 contentView 融合到一起
xib:在Main.storyboard選中Window,勾選屬性Full Size Content View
程式碼:
self.window.styleMask = self.window.styleMask | NSWindowStyleMaskFullSizeContentView;
- 不隱藏titleBar
- 隱藏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