Mac开发基础07-NSWindow(一)

NSWindow 是 macOS 应用中的基础窗口对象,它负责管理和展示应用的界面。理解和熟练使用 NSWindow 类的常见 API 和一些使用技巧,可以帮助你构建更复杂和功能强大的应用。以下是关于 NSWindow 的详细介绍:

1. 创建 NSWindow

基本创建

NSWindow 的初始化通常需要提供一个窗口的内容矩形,以及其他样式和属性。

Objective-C
NSRect frame = NSMakeRect(0, 0, 800, 600);
NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
                                                styleMask:(NSWindowStyleMaskTitled |
                                                           NSWindowStyleMaskClosable |
                                                           NSWindowStyleMaskResizable)
                                                  backing:NSBackingStoreBuffered
                                                    defer:NO];
[window setTitle:@"My Application"];
[window makeKeyAndOrderFront:nil];
Swift
let frame = NSRect(x: 0, y: 0, width: 800, height: 600)
let window = NSWindow(contentRect: frame,
                      styleMask: [.titled, .closable, .resizable],
                      backing: .buffered,
                      defer: false)
window.title = "My Application"
window.makeKeyAndOrderFront(nil)

2. 常见 API

窗口显示和操作

  • makeKeyAndOrderFront::使窗口成为键窗口并显示在所有其他窗口前面。
[window makeKeyAndOrderFront:nil]; // Objective-C
window.makeKeyAndOrderFront(nil) // Swift
  • orderFront::将窗口显示在前面但不成为键窗口。
[window orderFront:nil]; // Objective-C
window.orderFront(nil) // Swift
  • orderBack::将窗口置于所有其他窗口后面。
[window orderBack:nil]; // Objective-C
window.orderBack(nil) // Swift
  • close:关闭窗口。
[window close]; // Objective-C
window.close() // Swift
  • minimize:最小化窗口。
[window miniaturize:nil]; // Objective-C
window.miniaturize(nil) // Swift
  • deminiaturize:从 Dock 中恢复窗口。
[window deminiaturize:nil]; // Objective-C
window.deminiaturize(nil) // Swift

窗口属性

  • title:窗口的标题。
window.title = @"New Title"; // Swift
[window setTitle:@"New Title"]; // Objective-C
  • isVisible:检查窗口是否可见。
BOOL visible = [window isVisible]; // Objective-C
let visible = window.isVisible // Swift
  • isKeyWindow:检查窗口是否为键窗口。
BOOL isKey = [window isKeyWindow]; // Objective-C
let isKey = window.isKeyWindow // Swift
  • isMainWindow:检查窗口是否为主窗口。
BOOL isMain = [window isMainWindow]; // Objective-C
let isMain = window.isMainWindow // Swift
  • level:窗口的层级,用于控制窗口的显示优先级。
window.level = NSNormalWindowLevel; // Objective-C
window.level = .normal // Swift
  • backgroundColor:窗口的背景颜色。
window.backgroundColor = [NSColor blueColor]; // Objective-C
window.backgroundColor = .blue // Swift
  • opaque:窗口是否不透明。
window.opaque = NO; // Objective-C
window.isOpaque = false // Swift

窗口样式和行为

  • styleMask:设置窗口的样式掩码。
window.styleMask = (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable); // Objective-C
window.styleMask = [.titled, .closable, .resizable] // Swift
  • hasShadow:是否显示窗口阴影。
window.hasShadow = YES; // Objective-C
window.hasShadow = true // Swift
  • collectionBehavior:控制窗口在全屏、排他等方面的行为。
window.collectionBehavior = NSWindowCollectionBehaviorFullScreenPrimary; // Objective-C
window.collectionBehavior = .fullScreenPrimary // Swift

3. 代理方法

NSWindow 可以设置代理对象,以处理一些窗口事件。例如窗口关闭、移动、最小化等。

设置 Delegate

window.delegate = self;
window.delegate = self

以下代理方法示例都是以 Swift 为例,Objective-C 的格式仅有方法签名上的差异。

代理方法示例

// 窗口将要关闭
func windowWillClose(_ notification: Notification) {
    print("Window will close")
}

// 窗口已经关闭
func windowDidBecomeMain(_ notification: Notification) {
    print("Window did become main")
}

// 窗口已经迷你化
func windowDidMiniaturize(_ notification: Notification) {
    print("Window did miniaturize")
}

// 窗口已经恢复
func windowDidDeminiaturize(_ notification: Notification) {
    print("Window did deminiaturize")
}

// 窗口位置变动
func windowDidMove(_ notification: Notification) {
    print("Window did move")
}

// 窗口大小变动
func windowDidResize(_ notification: Notification) {
    print("Window did resize")
}

4. 高级用法和技巧

创建无标题栏窗口

无标题栏窗口适用于创建自定义窗口样式,如工具窗口、弹出窗口等。

NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
                                                styleMask:(NSWindowStyleMaskBorderless)
                                                  backing:NSBackingStoreBuffered
                                                    defer:NO];
window.opaque = NO;
window.backgroundColor = [NSColor clearColor];
let window = NSWindow(contentRect: frame,
                      styleMask: [.borderless],
                      backing: .buffered,
                      defer: false)
window.isOpaque = false
window.backgroundColor = .clear

创建全屏窗口

全屏窗口用于展示画廊、游戏等需要完整屏幕使用的应用。

NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
                                                styleMask:(NSWindowStyleMaskTitled |
                                                           NSWindowStyleMaskResizable |
                                                           NSWindowStyleMaskClosable)
                                                  backing:NSBackingStoreBuffered
                                                    defer:NO];
window.collectionBehavior = NSWindowCollectionBehaviorFullScreenPrimary;
let window = NSWindow(contentRect: frame,
                      styleMask: [.titled, .resizable, .closable],
                      backing: .buffered,
                      defer: false)
window.collectionBehavior = .fullScreenPrimary

透明窗口

透明窗口适用于浮动工具条、浮动菜单等。

NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
                                                styleMask:(NSWindowStyleMaskBorderless)
                                                  backing:NSBackingStoreBuffered
                                                    defer:NO];
window.opaque = NO;
window.backgroundColor = [[NSColor blackColor] colorWithAlphaComponent:0.5];
let window = NSWindow(contentRect: frame,
                      styleMask: [.borderless],
                      backing: .buffered,
                      defer: false)
window.isOpaque = false
window.backgroundColor = NSColor.black.withAlphaComponent(0.5)

5. 拖动窗口

无标题栏窗口通常需要手动实现拖动功能。可以通过 mouseDragged 方法来实现窗口的拖动。

Objective-C
- (void)mouseDragged:(NSEvent *)event {
    NSPoint windowOrigin = [self frame].origin;
    windowOrigin.x += event.deltaX;
    windowOrigin.y -= event.deltaY;
    [self setFrameOrigin:windowOrigin];
}
Swift
override func mouseDragged(with event: NSEvent) {
    var windowOrigin = self.frame.origin
    windowOrigin.x += event.deltaX
    windowOrigin.y -= event.deltaY
    self.setFrameOrigin(windowOrigin)
}

6. 处理窗口大小调整

窗口大小调整时,通常需要动态调整窗口内内容的布局。可以重载窗口的 setFrame: 方法来实现这一功能。

Objective-C
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag {
    [super setFrame:frameRect display:flag];
    // 更新子视图布局
    [self updateLayout];
}
Swift
override func setFrame(_ frameRect: NSRect, display flag: Bool) {
    super.setFrame(frameRect, display: flag)
    // 更新子视图布局
    self.updateLayout()
}

NSWindow 是一个功能强大且灵活的类,通过以上这些常见的 API 和高级技巧,可以更好地管理和展示 macOS 应用的窗口,并实现各种复杂的用户界面和交互。

posted @ 2024-08-06 14:21  Mr.陳  阅读(58)  评论(0编辑  收藏  举报