Mac开发之NSWindow自定义titlebar实现

本文详细介绍了一种在MacOS应用中实现自定义TabView的方法,利用Masonry布局框架进行精确控制,包括调整窗口标题栏、实现Tab按钮切换功能及响应全屏模式变化。

mac自定义titlebar

其中使用到了布局框架:Masonry

1. tab按钮实现

#import <Cocoa/Cocoa.h>

@interface ZLTabView : NSView

// 回调到主控制器
@property (nonatomic, copy) void(^TabSelect)(NSInteger sender);

// 外部调用选中第几个按钮 0、1、2、……
- (void)select:(NSInteger)index;

@end

#import "ZLTabView.h"

@interface ZLTabView()

// 记录当前选中按钮,方便状态切换
@property (nonatomic, weak) NSButton *curButton;

@end

@implementation ZLTabView

- (instancetype)init {

    if(self = [super init]) {

        [[NSBundle mainBundle] loadNibNamed:@"ZLTabView" owner:self topLevelObjects:nil];

        NSNib *cnib = [[NSNib alloc] initWithNibNamed:@"ZLTabView" bundle:nil];

        NSArray *viewsArray = [[NSArray alloc] init];
        [cnib instantiateWithOwner:nil topLevelObjects:&viewsArray];

        for (int i = 0; i < viewsArray.count; i++) {
            if ([viewsArray[i] isKindOfClass:[ZLTabView class]]) {
                self = viewsArray[i];
                _curButton = self.subviews.firstObject;
                break;
            }
        }
    }
    return self;
}

- (void)select:(NSInteger)index {
    [self courseIntroClick:self.subviews.firstObject];
}

- (IBAction)courseIntroClick:(NSButton *)sender {
    NSLog(@"clicked %d", sender.state);
    self.curButton.state = !self.curButton.state;
    self.curButton = sender;
    self.TabSelect(sender.tag-9);  // 我设置的button的tag从9开始
}

@end

xib文件如图所示:

mac自定义titlebar之tabview自定义xib

2. window的titlebar布局调整

// 遵守<NSWindowDelegate>协议

// 隐藏标题
self.window.titleVisibility = NSWindowTitleHidden;

// 在恰当的地方添加顶部tab按钮
[[self.window standardWindowButton:NSWindowCloseButton].superview addSubview:self.tabview];


// 根据是否全屏刷新布局
- (void)windowResizeAction:(BOOL)fullscreen{

    // 获取titlebar视图
    NSView *titleBarContainerView = [self.window standardWindowButton:NSWindowCloseButton].superview.superview;
    [titleBarContainerView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(@0);
        make.right.equalTo(@0);
        make.top.equalTo(@0);
        if (fullscreen) {
            make.height.equalTo(@22);
        } else {
            make.height.mas_equalTo(ZLTitlebarHeight);
        }
    }];

    // 关闭、最小化等按钮
    NSButton *closeBtn = [self.window standardWindowButton:NSWindowCloseButton];
    NSButton *zoomBtn = [self.window standardWindowButton:NSWindowZoomButton];
    NSButton *minBtn = [self.window standardWindowButton:NSWindowMiniaturizeButton];


    for (NSView *buttonView in @[closeBtn, zoomBtn, minBtn]) {
        [buttonView mas_remakeConstraints:^(MASConstraintMaker *make) {
            if (fullscreen) {
                make.top.mas_equalTo(3.0);
            } else {
                make.centerY.mas_equalTo(buttonView.superview.mas_centerY);
            }
        }];
    }
}

#pragma mark - WindowDelegate Methods
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
    [self windowResizeAction:true];
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
    [self windowResizeAction:false];
}
- (void)windowDidResize:(NSNotification *)notification {
    [self windowResizeAction:false];
}

3. tabview的使用

self.tabview = [[ZLTabView alloc] init];
__weak typeof(self) weakSelf = self;
self.tabview.TabSelect = ^(NSInteger sender) {
    NSLog(@"%d", sender);
    if (sender==0) {

        // 这里切换控制器
        weakSelf.window.contentViewController = firstVC;

    } else if(sender==1) {


    } else {

    }
};

// 将tabview添加到titlebar上
[[self.window standardWindowButton:NSWindowCloseButton].superview addSubview:self.tabview];
// 设置默认选中项
[self.tabview select:0];

// 设置tabview的位置
[self.tabview mas_updateConstraints:^(MASConstraintMaker *make) {
    make.size.mas_equalTo(NSMakeSize(260, 40));
    make.centerX.mas_equalTo(self.tabview.superview.mas_centerX);
    make.centerY.mas_equalTo(self.tabview.superview.mas_centerY);
}];
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ADreamClusive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值