模态的几种方式: 该方案参考自weixin_34064653
1、新打开的子窗口与父窗口相互独立,即使关闭父窗口子窗口也不会受到任何影响。
TableViewController *vc = [[TableViewController alloc] initWithWindowNibName:@"TableViewController"];
[vc showWindow:nil];
2、子窗口被弹出时,父窗口会无法接收鼠标、键盘事件的响应。
TableViewController *vc = [[TableViewController alloc] initWithWindowNibName:@"TableViewController"];
[NSApp runModalForWindow:vc.window];
3、子窗口被弹出时,只有父窗口的菜单栏、快捷键等可以接收鼠标、键盘事件的响应。
TableViewController *vc = [[TableViewController alloc] initWithWindowNibName:@"TableViewController"];
sessionCode = [NSApp beginModalSessionForWindow:vc.window];
特别注意
在所有的Modal形式下(Modal Windows和Modal Sessions),都需要在父窗口监听NSWindowWillCloseNotification
的通知。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:nil];
并且在windowWillClose方法中停止Modal:
- (void)windowWillClose:(NSNotification *)notification {
[[NSApplication sharedApplication] stopModal];
if (sessionCode != 0) {
//窗口以Modal sessions启动时,停止session
[[NSApplication sharedApplication]endModalSession:sessionCode];
}
}
由于视图本身并没有提供背景、边框、圆角等属性,但可以利用layer属性来控制这些效果,使用层属性之前必须先调用wantsLayer
为YES。
self.wantsLayer = YES;
self.layer.backgroundColor = [NSColor redColor].CGColor;
self.layer.borderColor = [NSColor greenColor].CGColor;
self.layer.borderWidth = 2;
self.layer.cornerRadius = 20;
加载xib
1、首先使用 NSNib 加载 OutPanel.xib 资源文件;
2、定义存储 xib 文件中可加载的对象数组;
3、使用 nib 的 instantiate 方法实例化 xib 资源文件中的类,将所有的类存储在对象数组中;
4、循环遍历访问数组,找到我们需要的类型的对象实例,返回。
- (OutPanel *)outPanel {
if (!_outPanel) {
NSNib *nib = [[NSNib alloc] initWithNibNamed:@"OutPanel" bundle:nil];
NSArray *topLevelObjects;
if ([nib instantiateWithOwner:self topLevelObjects:&topLevelObjects]) {
for (id topLevelObject in topLevelObjects) {
if ([topLevelObject isKindOfClass:[OutPanel class]]) {
_outPanel = topLevelObject;
break;
}
}
}
}
return _outPanel;
}
加载NSWindowController A:
可以用以下方法初始化windowController A,那么在A中就不用做其他处理了。
_rootVC = [[CustomRootVC alloc] initWithWindowNibName:@"CustomRootVC"];
[self.rootVC showWindow:self];
也可以在被调用的WindowController A中添加
- (NSNibName)windowNibName {
return @"CustomRootVC";
}
调用方法:
_rootVC = [[CustomRootVC alloc] init];
[self.rootVC showWindow:self];
将App窗口移到最前并置为活跃状态:
[self.window makeKeyAndOrderFront:self];
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps];
代码创建window
首先,需要在main.m
设置代理:
#import
#import "AppDelegate.h"
int main(int argc, const char * argv[]) {
// 设置delegate
NSApplication *app = [NSApplication sharedApplication];
id delegate = [[AppDelegate alloc] init];
app.delegate = delegate;
return NSApplicationMain(argc, argv);
}
再者,就是在AppDelegate
里设置:
#import "AppDelegate.h"
#import "RootViewController.h"
@interface AppDelegate ()
@property (nonatomic, strong) NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
CGSize size = [NSScreen mainScreen].frame.size;
NSRect rect = CGRectMake(0, 0, size.width * 0.5, size.height * 0.5);
NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;
// 创建window
self.window = [[NSWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:YES];
self.window.title = @"代码创建的window";
// 设置最小和最大窗口尺寸
self.window.contentMinSize = CGSizeMake(size.width * 0.5, size.height * 0.5);
self.window.contentMaxSize = CGSizeMake(size.width * 0.75, size.height * 0.75);
// 将窗口移到最前,并居中显示
[self.window makeKeyAndOrderFront:self];
[self.window center];
// 这个必须放到下面
self.window.contentViewController = [[RootViewController alloc] init];
}
最后,RootViewController
里,要在loadView
里创建self.view
:
- (void)loadView {
NSRect frame = [[[NSApplication sharedApplication] mainWindow] frame];
self.view = [[NSView alloc] initWithFrame:frame];
}