根据 bhaller 之前给出的建议,下面的演示使用第二个底层窗口,其中包含一个彩色填充视图,并且比主窗口略大,因此它的边缘是可见的。底层窗口通过窗口代理绑定到主窗口,以同步更改位置/大小,并且可以显示或隐藏。该演示可以在 Xcode 中运行,只需将主文件替换为以下代码并另外删除 Apple 提供的 AppDelegate 文件(以避免重复符号错误):
#import <Cocoa/Cocoa.h>
@interface CustomView : NSView
@end
@implementation CustomView
- (id)initWithFrame:(NSRect)frameRect{
if ((self = [super initWithFrame:frameRect]) != nil) {
// Add initialization code here
}
return self;
}
- (void)drawRect:(NSRect)rect {
// ****** Background ***** //
[[NSColor redColor] set];
[NSBezierPath fillRect:rect];
}
// ----- Use this if you want 0,0 (origin) to be top, left ---- //
// ----- Otherwise origin will be at bottom, left (Unflipped) ----- //
-(BOOL)isFlipped
{
return YES;
}
@end
@interface WindowDelegate : NSObject <NSWindowDelegate>
@property(strong) NSWindow *underlayWnd;
@end
@implementation WindowDelegate
- (void)windowDidResize:(NSNotification *)notification {
NSRect frameR = NSMakeRect([notification.object frame].origin.x - 10, [notification.object frame].origin.y - 10, [notification.object frame].size.width + 20, [notification.object frame].size.height + 20);
[_underlayWnd setFrame:frameR display:YES];
}
- (void)windowDidEndLiveResize:(NSNotification *)notification {
NSRect frameR = NSMakeRect([notification.object frame].origin.x - 10, [notification.object frame].origin.y - 10, [notification.object frame].size.width + 20, [notification.object frame].size.height + 20);
[_underlayWnd setFrame:frameR display:YES];
}
- (void)windowDidMove:(NSNotification *)notification {
NSRect frameR = NSMakeRect([notification.object frame].origin.x - 10, [notification.object frame].origin.y - 10, [notification.object frame].size.width + 20, [notification.object frame].size.height + 20);
[_underlayWnd setFrame:frameR display:YES];
}
- (void)windowDidMiniaturize:(NSNotification *)notification {
NSRect frameR = NSMakeRect([notification.object frame].origin.x - 10, [notification.object frame].origin.y - 10, [notification.object frame].size.width + 20, [notification.object frame].size.height + 20);
[_underlayWnd setFrame:frameR display:YES];
}
@end
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
NSWindow *window;
NSWindow *underlayWnd;
WindowDelegate *windowDelegate;
CustomView *view;
}
- (void) myShowAction;
- (void) myHideAction;
- (void) buildMenu;
- (void) buildWindow;
@end
@implementation AppDelegate
-(void) myHideAction {
[underlayWnd orderOut:nil];
}
-(void) myShowAction {
[underlayWnd orderFront:nil];
[window makeKeyAndOrderFront: nil];
}
- (void) buildMenu {
NSMenu *menubar = [NSMenu new];
NSMenuItem *menuBarItem = [NSMenuItem new];
[menubar addItem:menuBarItem];
[NSApp setMainMenu:menubar];
NSMenu *appMenu = [NSMenu new];
NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(terminate:) keyEquivalent:@"q"];
[appMenu addItem:quitMenuItem];
[menuBarItem setSubmenu:appMenu];
}
- (void) buildWindow {
windowDelegate = [[WindowDelegate alloc]init];
#define _wndW 700
#define _wndH 550
window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )
styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable
backing: NSBackingStoreBuffered defer: NO];
[window center];
[window setTitle: @"Test window"];
[window setDelegate: windowDelegate];
[window makeKeyAndOrderFront: nil];
NSRect frameR = NSMakeRect([window frame].origin.x - 10, [window frame].origin.y - 10, [window frame].size.width + 20, [window frame].size.height + 20);
underlayWnd = [[NSWindow alloc] initWithContentRect:frameR styleMask: NSWindowStyleMaskBorderless backing: NSBackingStoreBuffered defer: NO];
[underlayWnd setIgnoresMouseEvents:true];
[underlayWnd orderWindow:NSWindowBelow relativeTo:0];
// **** Custom View **** //
view = [[CustomView alloc]initWithFrame:NSMakeRect(0,0,frameR.size.width, frameR.size.height)];
[view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
[[underlayWnd contentView] addSubview:view]
[windowDelegate setUnderlayWnd:underlayWnd];
// **** Hide Button **** //
NSButton *hideBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 30, 30, 165, 30 )];
[hideBtn setBezelStyle:NSBezelStyleRounded ];
[hideBtn setTitle: @"Hide underlay window"];
[hideBtn setAction: @selector (myHideAction)];
[[window contentView] addSubview: hideBtn];
// **** Show Button **** //
NSButton *showBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 210, 30, 165, 30 )];
[showBtn setBezelStyle:NSBezelStyleRounded ];
[showBtn setTitle: @"Show underlay window"];
[showBtn setAction: @selector (myShowAction)];
[[window contentView] addSubview: showBtn];
// **** Quit btn **** //
NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 5, 40, 40 )];
[quitBtn setBezelStyle:NSBezelStyleCircular ];
[quitBtn setTitle: @"Q" ];
[quitBtn setAutoresizingMask: NSViewMinXMargin];
[quitBtn setAction:@selector(terminate:)];
[[window contentView] addSubview: quitBtn];
}
- (void) applicationWillFinishLaunching: (NSNotification *)notification
{
[self buildMenu];
[self buildWindow];
}
- (void) applicationDidFinishLaunching: (NSNotification *)notification
{
}
@end
int main (){
NSApplication *application = [NSApplication sharedApplication];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application run];
return 0;
}