MAC-OS开发笔记一 NSWindow

作者: 断水殇 | 来源:发表于2017-08-07 17:42 被阅读237次

    创建新的Xcode工程,选择 macOS,如下图,点击Next,如下图。过程与创建iOS项目一样。

    默认会有main.storyboard文件,个人喜好以及习惯问题,我删除了该文件,于是,第一个问题出现了。(个人习惯:带着问题去学习)

    问题 一、窗口怎么显示在屏幕上?

    在 AppDelegate.m 文件里我这样写:

    @interfaceAppDelegate()

    @property(nonatomic,strong)NSWindow*mainWindow;//窗口

    @end

    @implementationAppDelegate

    - (void)applicationDidFinishLaunching:(NSNotification*)aNotification {

    {//设置window

    /**

    创建方法:重点说一下第二个参数styleMask,添加了一大堆枚举,以下列出常用的几个

    NSWindowStyleMaskMiniaturizable  可最小化

    NSWindowStyleMaskResizable可调整尺寸,即拉伸

    NSWindowStyleMaskTitled          显示标题

    NSWindowStyleMaskClosable        可关闭,如果不加,则关闭按钮处显示一个灰色按钮,不可点击

    */

    _m_windowMain= [[NSWindowalloc]initWithContentRect:CGRectMake(0,0,800,600)styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable|NSWindowStyleMaskClosable|NSWindowStyleMaskUtilityWindowbacking:NSBackingStoreRetaineddefer:NO];

    //全屏按钮显示以及点击后效果,默认为“+”号,点击后在当前屏幕放大;这里设置为新桌面放大

    _m_windowMain.collectionBehavior=NSWindowCollectionBehaviorFullScreenPrimary;

    _m_windowMain.delegate=self;

    [_m_windowMaincenter];

    [_m_windowMainmakeKeyWindow];

    //设置最小缩放

    [_m_windowMainsetMinSize:CGSizeMake(400,300)];

    //将window与APP绑定,如果不绑定,无法显示Window。

    [NSAppbeginModalSessionForWindow:_m_windowMain];

    }

    }

    @end

    注意最后那句注释,[NSAppbeginModalSessionForWindow:_m_windowMain]这句话看似已经完成Window显示到屏幕上这个工作了,实则不然,运行之后Window没有显示。与iOS不同之处,我们还要对main.m文件进行更改。如果是用main.storyboad文件的朋友则不需要,因为OS开发的main.storyboad比iOS的多做了些功能。

    在main.m文件中修改并添加如下代码:

    intmain(intargc,constchar* argv[]) {

    NSApplication*applicaton = [NSApplicationsharedApplication];

    iddelegete = [[AppDelegatealloc]init];

    applicaton.delegate= delegete;

    returnNSApplicationMain(argc, argv);

    }

    再次运行,正常情况下你就能看到Window了,但是是个灰色的,那么再来看第二个问题。

    问题 二、如何更改背景色?

    其实看了上一段代码,熟悉iOS开发的朋友应该能看出来,iOS开发中UIKit中的东西是用UI开头的,比如UIWindow,UIView等,而在OS开发中,与之相对于就是NSWindow,NSView了。

    NSWindow有个属性叫contentView,继承NSView,所以改变Window的背景色,可以从这个属性开始。与UIView不同的是NSView没有backgroundColor属性,不过还好,有个layer可以用,于是按照思路猜测,是这样写的:

    [_m_windowMain.contentView.layersetBackgroundColor:[[NSColorwhiteColor]CGColor]];

    运行起来后,然并卵!!!就像iOS开发中给UIView的子类设置圆角一样,需要开启允许裁剪开关,查了些资料,找到这句话:

    _m_windowMain.contentView.wantsLayer=YES;

    本人英语水平一般般,大概是告诉编译器:这个NSView,我要使用它的Layer,所以对它的Layer设置要有效🤣。

    到这里运行程序之后,背景色是白色,点击关闭按钮,窗口消失,但是怎么再让窗口显示呢?

    问题 三、如何关闭窗口后再显示?

    首先说说我的思路:点击关闭,窗口消失,点击dock中的Icon,窗口再显示;可是刚才点击Dock是没有反应的,所以点击Dock应该是有个方法的。

    /**

    点击Dock Icon事件

    flag:窗口存在YES;窗口关闭NO

    */

    - (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication hasVisibleWindows:(BOOL)flag {

    if(!flag){

    [NSAppactivateIgnoringOtherApps:NO];//取消其他程序的响应

    [_m_windowMainmakeKeyAndOrderFront:self];//主窗口显示自己方法一

    //[_mainWindow orderFront:nil];           //主窗口显示自己方法二

    returnYES;

    }

    returnNO;

    }

    上述方法是NSApplicationDelegate中的,监听了点击Dock中的Icon。看注释应该知道是怎么回事。运行,点击关闭,点击Dock中的Icon,Window出现了,别高兴太早,试试再次点击关闭,你会发现,关闭按钮失效了。好吧,再查……

    - (BOOL)windowShouldClose:(id)sender {

    [_m_windowMainorderOut:nil];//窗口消失

    returnNO;

    }

    麻烦再添加上述代码,此方法是NSWindowDelegate的,看来目前用过的程序都是假关闭,因为returnNO,意思是不让Window关闭。该方法是监听点击Window上的关闭按钮,而像其他一般程序那样的关闭再打开再关闭的,得用[_m_windowMainorderOut:nil]来实现。(PS:苹果API也不给个注释什么的,参数我都不知道咋给,暂时给nil)。

    现在先抛出一个问题,后面做到那块了再去验证:视频播放器(比如爱奇艺),关闭窗口后视频停止了播放,音乐播放器(比如QQ音乐),关闭窗口后音乐还在播放。这两种关闭窗口的方法是否为同一种方法?或者类似于iOS开发,有个“程序后台执行权限”?

    问题 四、窗口随着鼠标拖动放大缩小

    直接上货吧,找NSApplicationDelegate,实现如下几个方法:

    /**

    拖动放大缩小、点击全屏(换桌面全屏)时

    可以在此方法中更改界面布局,如果未设置最小

    */

    - (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {

    returnframeSize;

    }

    /**

    当点击“+”号,或者双击放大时,即在本屏幕方法

    以下两个方法都是,可以根据返回值控制想要的效果

    第一个方法只有放大的时候会被调用

    第二个放大缩小都会调用

    双击放大时不会调用上面的方法(windowWillResize),因此都需要实现

    */

    - (NSRect)windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)newFrame {

    returnnewFrame;

    }

    - (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame {

    if(newFrame.size.height>350) {

    returnYES;

    }

    returnNO;

    }

    关于 窗口放大缩小这两个方法也就够了,还有其他的方法,但是没搞清楚来龙去脉。

    相关文章

      网友评论

        本文标题:MAC-OS开发笔记一 NSWindow

        本文链接:https://www.haomeiwen.com/subject/otmalxtx.html