OSX Dev Day 7 and 8 - Menu Bar
step 1 Add Menu
1.create project.
2.add variable(NSStatusItem *statusItem) to AppDelegate.h and initialize.
3.add some codes:
_statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; NSStatusBarButton *button = [_statusItem button]; if(button){ button.image = [NSImage imageNamed:@"zuan"]; button.action = @selector(showWeather:); }
- (void)showWeather:(NSStatusBarButton *)sender { NSLog(@"Sunshine"); }
4.click 'Assets.xcassets',import image 'zuan'
5.change the zuan's Devices to Mac and drag 'zuan' to mac 2x
step 2 Hide Window
6.back to storyboard,change window controller 'is Initial Controller' to off.
7.project setting, info,add 'chose application is agent',set value is yes.
step 3 Add Menu Item
8.comment out the code:
//button.action = @selector(showWeather:);
9.add some code:
NSMenu *menu; menu = [[NSMenu alloc] init]; [menu addItem:[[NSMenuItem alloc] initWithTitle:@"Show Weather" action:@selector(showWeather:) keyEquivalent:@"S"] ]; [menu addItem:[NSMenuItem separatorItem]]; [menu addItem:[[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"] ]; _statusItem.menu = menu;
Step 4 Add popover
10.add new file "WeatherViewController"(subclass:ViewController).
- (id) initWithCustom{ self = [super initWithNibName:@"WheatherViewController" bundle:nil]; return self; }
11.add variable(NSPopover * popover ) and initialize.
_popover = [[NSPopover alloc] init]; _popover.contentViewController = [[WheatherViewController alloc] initWithCustom];
11.add method:
- (void)toggleWeather:(NSStatusBarButton *)sender{ if([_popover isShown]){ [_popover performClose:sender]; }else{ NSStatusBarButton *button = _statusItem.button; if(button){ [_popover showRelativeToRect:button.bounds ofView:button preferredEdge:NSRectEdgeMinY]; } } }
Step 5 Event Monitor
14.add new class'EventMonitor'.
#import <Cocoa/Cocoa.h> @interface EventMonitor : NSObject @property id monitor; @property NSEventMask mask; @property void (^handler)(NSEvent *); - (id) initWithMaskAndHandler:(NSEventMask)mask handler:(void (^)(NSEvent *))handler; - (void) start; - (void) stop; @end
#import "EventMonitor.h" @implementation EventMonitor - (id) initWithMaskAndHandler:(NSEventMask)mask handler:(void (^)(NSEvent *)) handler { _mask = mask; _handler = handler; return self; } - (void) deinit{ [self stop]; } - (void) start{ _monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:_mask handler:_handler]; } - (void) stop{ if(_monitor != nil ){ [NSEvent removeMonitor:_monitor]; _monitor = nil; } } @end
15.modify some code:
button.action = @selector(toggleWeather:);
- (void)closePopover:(id)sender{ [_popover performClose:sender]; [_eventMonitor stop]; } - (void)showPopover:(id)sender{ NSStatusBarButton *button = _statusItem.button; if(button){ [_popover showRelativeToRect:button.bounds ofView:button preferredEdge:NSRectEdgeMinY]; } [_eventMonitor start]; } - (void)toggleWeather:(NSStatusBarButton *)sender{ if([_popover isShown]){ [self closePopover:sender]; }else{ [self showPopover:sender]; } }
16.add some code in AppDelegate.h and AppDelegate.m:
#import "WeatherViewController.h" @property EventMonitor *eventmonitor;
_eventMonitor = [[EventMonitor alloc] initWithMaskAndHandler:NSEventMaskLeftMouseUp|NSEventMaskRightMouseUp handler:^(NSEvent *h) { if([_popover isShown]){ [self closePopover:h]; } }];
done!