文档章节

OS开发笔记一 NSWindow

断水殇
 断水殇
发布于 2017/08/07 18:00
字数 1355
阅读 103
收藏 0

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

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

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

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

@interface AppDelegate ()<NSWindowDelegate>
@property (nonatomic, strong) NSWindow *mainWindow; //窗口
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    {//设置window 
        /**
        创建方法:重点说一下第二个参数 styleMask,添加了一大堆枚举,以下列出常用的几个
           NSWindowStyleMaskMiniaturizable  可最小化
           NSWindowStyleMaskResizable       可调整尺寸,即拉伸
           NSWindowStyleMaskTitled          显示标题
           NSWindowStyleMaskClosable        可关闭,如果不加,则关闭按钮处显示一个灰色按钮,不可点击
        */
        _m_windowMain = [[NSWindow alloc]initWithContentRect:CGRectMake(0, 0, 800, 600) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskUtilityWindow backing:NSBackingStoreRetained defer:NO];
        
        //全屏按钮显示以及点击后效果,默认为“+”号,点击后在当前屏幕放大;这里设置为新桌面放大
        _m_windowMain.collectionBehavior = NSWindowCollectionBehaviorFullScreenPrimary;
        
        _m_windowMain.delegate = self;
        
        [_m_windowMain center];
        
        [_m_windowMain makeKeyWindow];
      
        //设置最小缩放
        [_m_windowMain setMinSize:CGSizeMake(400, 300)];

        //将window与APP绑定,如果不绑定,无法显示Window。
        [NSApp beginModalSessionForWindow:_m_windowMain];
    }
}
@end

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

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

int main(int argc, const char * argv[]) {
    
    NSApplication *applicaton = [NSApplication sharedApplication];
    
    id delegete = [[AppDelegate alloc]init];
    
    applicaton.delegate = delegete;
    
    return NSApplicationMain(argc, argv);
}

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

其实看了上一段代码,熟悉iOS开发的朋友应该能看出来,iOS开发中UIKit中的东西是用UI开头的,比如UIWindow,UIView等,而在OS开发中,与之相对于就是NSWindow,NSView了。
NSWindow有个属性叫contentView,继承NSView,所以改变Window的背景色,可以从这个属性开始。与UIView不同的是NSView没有backgroundColor属性,不过还好,有个layer可以用,于是按照思路猜测,是这样写的:

[_m_windowMain.contentView.layer setBackgroundColor:[[NSColor whiteColor] 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){
        [NSApp activateIgnoringOtherApps:NO];//取消其他程序的响应
        [_m_windowMain makeKeyAndOrderFront:self];//主窗口显示自己 方法一
        //[_mainWindow orderFront:nil];           //主窗口显示自己 方法二
        return YES;
    }
    return NO;
}

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

- (BOOL)windowShouldClose:(id)sender {
    [_m_windowMain orderOut:nil];//窗口消失
    return NO;
}

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

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

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

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

/**
 拖动放大缩小、点击全屏(换桌面全屏)时
 可以在此方法中更改界面布局,如果未设置最小
 */
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize {
    return frameSize;
}

/**
 当点击“+”号,或者双击 放大时,即在本屏幕方法
 以下两个方法都是,可以根据返回值控制想要的效果
    第一个方法只有放大的时候会被调用
    第二个放大缩小都会调用
    双击放大时不会调用上面的方法(windowWillResize),因此都需要实现
 */
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame {
    return newFrame;
}
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame {   
    if (newFrame.size.height > 350) {
        return YES;
    }
    return NO;
}

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

© 著作权归作者所有

断水殇
粉丝 1
博文 8
码字总数 7472
作品 0
西安
iOS工程师
私信 提问
窗口分离控件--WAYSourceListWindow

WAYSourceListWindow 是 NSWindow 的子类,可以垂直分离窗口空间,把主视图放在左边,详情视图放在右边,类似提醒或者笔记。

叶秀兰
2014/12/24
150
0
AppKit 类集合--DejalAppKitCategories

DejalAppKitCategories 是 OS X 上 AppKit 类集合,添加了一些有用的方法到类中:NSMenu, NSTableView,NSTextView 等等: NSButton+Dejal NSImage+Dejal NSMenu+Dejal NSOutlineView+Dejal ......

叶秀兰
2015/02/06
297
0
关于setneedsdisplay

1、在Mac OS中NSWindow的父类是NSResponder,而在i OS 中UIWindow 的父类是UIVIew。程序一般只有一个窗口但是会又很多视图。 2、UIView的作用:描画和动画,视图负责对其所属的矩形区域描画、...

meilidashijie
2013/01/09
0
0
opengl 在 Mac os x下默认是2.1的问题

(void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application NSRect mainDisplayRect = [[NSScreen mainScreen] frame]; ......

大黄
2014/12/25
0
0
[Cocoa] NSApplication 简介

每一个应用程序都必须有一个 NSApplication 单例对象,它管理应用程序的主事件循环。在 main() 函数中,我们在 NSApplicationMain 里创建该单例对象,并启动事件循环。NSApplicationMain 的功...

木木情深
2013/12/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java的战争

本文来自微信公众号: 金捷幡(ID:jin-jiefan) ,作者:金捷幡,封面:拉里·埃里森(东方IC) 2019年5月,彻底撕破脸的特朗普掀起对华为的战争,谷歌被迫吊销了华为的Android授权。开源软...

Java领航员
39分钟前
1
0
超详细的LM3414MRX/NOPB规格参数介绍就在这里

超详细的LM3414MRX/NOPB规格参数介绍就在这里 描述 LM3414和LM3414MRX/NOPB是具有1-A 60 W(1)共阳极功能的恒流降压LED驱动器。它们适用于驱动单串3-W HBLED,效率高达96%。它们可接受4.5...

不能吃肉的仙女
45分钟前
1
0
Eclipse国内镜像源配置方法

Table of Contents 我们在国内从官网下载Eclipse以及插件非常慢,那么,有没有方法变快呢? 有,那就是使用国内的公开镜像源替换官方源。 1 下载Eclipse 首先,我们看一个链接地址: http:/...

求神
今天
7
0
java 请求服务

一.第一种基于java web http 请求服务,必须用tomcat 容器启动才能对外提供服务 在maven 工程中pox 文件导入jar <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>h......

zaolonglei
今天
5
0
HDFS工作机制——自开发分布式数据采集系统

需求描述: 在业务系统的服务器上,业务程序会不断生成业务日志(比如网站的页面访问日志) 业务日志是用log4j生成的,会不断地切出日志文件,需要定期(比如每小时)从业务服务器上的日志目...

须臾之余
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部