Capture dragging outside of UIControl -- UILongPressGestureRecognizer - objective-c

I'm trying to implement an async voice recording feature. There's a button that has a UILongPressGestureRecognizer and this starts the recording. Right now, when they let go, the recording is saved and sent.
#pragma mark - Actions
- (void) recordButtonPressed:(UILongPressGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan) {
[self.voiceRecorderView.recordButton setImage:[UIImage imageNamed:kWSGreyDotXLarge] forState:UIControlStateNormal];
[self startRecording];
}
if (gesture.state == UIGestureRecognizerStateEnded) {
[self stopRecording];
[self.voiceRecorderView.recordButton setImage:[UIImage imageNamed:kWSPinkDotXLarge] forState:UIControlStateNormal];
}
}
This works, but now I need to copy the now standard feature of allowing the user to drag their finger off the button while it's pressed to cancel the recording.
How to add a gestureRecognizer to tell if a user drags outside the control but is still pressing it?

I hope it will work for you....
BOOL cancelflag;
UIButton *recordBtn;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
[longPress setDelegate:self];
[recordBtn addGestureRecognizer:longPress];
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)longPressRecognizer
{
if(longPressRecognizer.state == UIGestureRecognizerStateBegan)
{
if (!stopBtnFlag)
{
if (!audioRecorder.recording)
{
[self performSelectorOnMainThread:#selector(setUpAudioRecorder) withObject:nil waitUntilDone:YES];
[audioRecorder record];
NSLog(#"Recording...");
}
stopBtnFlag = YES;
cancelflag =YES;
}
}
else if (longPressRecognizer.state == UIGestureRecognizerStateChanged)
{
[audioRecorder stop];
stopBtnFlag = NO;
NSLog(#"moved");
}
else if (longPressRecognizer.state == UIGestureRecognizerStateEnded)
{
if(cancelflag)
{
[audioRecorder stop];
[self playmusic];
}
}
}

#Jaleel's answer gave me a start. Here's a complete working version:
- (void) recordButtonPressed:(UILongPressGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan) {
[self.voiceRecorderView setCancelText:WSCancelLabelTextStart];
if (!audioRecorder.recording)
{
[self startRecording];
}
cancelflag = NO;
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
CGPoint touchPoint = [gesture locationInView:self.voiceRecorderView];
if (!CGRectContainsPoint(self.voiceRecorderView.recordButton.frame, touchPoint )) {
cancelflag = YES;
[self.voiceRecorderView.recordButton setImage:[UIImage imageNamed:kWSGreyDotXLarge] forState:UIControlStateNormal];
[self.voiceRecorderView setCancelText:WSCancelLabelTextCancelling];
}
else {
cancelflag = NO;
[self.voiceRecorderView.recordButton setImage:[UIImage imageNamed:kWSPinkDotXLarge] forState:UIControlStateNormal];
[self.voiceRecorderView setCancelText:WSCancelLabelTextStart];
}
}
else if (gesture.state == UIGestureRecognizerStateEnded) {
[self stopRecording];
if(!cancelflag)
{
[self sendRecording:self.recordingURL];
}
else {
[self.voiceRecorderView setCancelText:WSCancelLabelTextCancelled];
}
[self.voiceRecorderView resetView];
}
}

Related

iOS7 UISearchDisplayController bug with Navigation Bar not automatically hidden

Reveal shows the following:
-> UINavigationBar
-> UINavigationTransitionView
->UITableView
->UISearchDisplayController
->UISearchBar
When I hit the searchBar the searchDisplayController does not hide the NavigationBar instead it reveals half of it.
I do not use auto layout (so not constraints), I am using a UITableViewController, I cannot use the new UISearchController and I am looking for a solution to either make it work as it should or either do not allow it to expand. The problem occurs only for the iPad. The project supports iOS7 and above.
I am trying to catch everything in the following methods:
#pragma mark - UISearchDisplayController Delegate
- (void)searchDisplayController:(UISearchDisplayController *)controller willHideSearchResultsTableView:(UITableView *)tableView {
self.onlineSearchRequestUUID = [NSUUID UUID];
dispatch_async(self.searchSerialQueue, ^{
if ([self.parentVC needsEmail]) {
self.capiContact->setFilter(CAPIContactFilter::WithEmail, "");
} else {
self.capiContact->setFilter(CAPIContactFilter::All, "");
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.parentVC.tableView reloadData];
});
});
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
dispatch_async(self.searchSerialQueue, ^{
[self filterContentForSearchText:searchString
scope:[controller.searchBar scopeButtonTitles][[controller.searchBar selectedScopeButtonIndex]]];
dispatch_async(dispatch_get_main_queue(), ^{
[controller.searchResultsTableView reloadData];
if ([searchString length] == 0) {
[self.parentVC.tableView reloadData];
}
});
});
return NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
dispatch_async(self.searchSerialQueue, ^{
[self filterContentForSearchText:[controller.searchBar text]
scope:[controller.searchBar scopeButtonTitles][searchOption]];
dispatch_async(dispatch_get_main_queue(), ^{
[controller.searchResultsTableView reloadData];
});
});
return NO;
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
if (![self.tableView isEditing]) {
searchBar.showsScopeBar = YES;
[searchBar sizeToFit];
_oldnavCol = [self.navigationController.view.backgroundColor copy];
#try {
[self.navigationController.view setBackgroundColor:[[[[self.parentVC.searchDisplayController searchBar] subviews][0] subviews][1] barTintColor]];
}
#catch (NSException *exception) {
LogDebug(#"%#", exception);
}
return YES;
}
return NO;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
double delayInSeconds = .5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
[self.navigationController.view setBackgroundColor:_oldnavCol];
_oldnavCol = nil;
}
});
return YES;
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
//Here is where i have tried most of my tries to make it work with hacks but with no luck.
//self.navigationController.navigationBar.translucent = YES;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
self.searchDisplayController.searchBar.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 88);
}
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
self.tableSearchText = searchText;
//some code here
if ([searchText length]) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSString *uuid = [self.onlineSearchRequestUUID UUIDString];
//some more code here
});
}
}
I don't think I am missing something.
Any help would be appreciated.
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[[[parentViewController navigationController] navigationBar] setHidden: YES];
}
}
for my case parentViewController is either self or self.parentVC and it works like a charm.

pan gesture recognise button issue

I set a pan gesture recogniser to recognise my touch on some buttons and am running into the following issue. I am trying to add an action to each of the buttons. I'm testing this by telling each different button to become highlighted when I touch them. So far when I keep my finger pressed on the screen en slide around only button1 and button2 show up (as written in the code).
But for some reason I can still see other buttons highlight the same way when I press them individually. Any idea how to solve this so that they only respond to. If button.tag == 3 etc.. Then respond? Here is the code. (This is all the code in the project and a few buttons in the interface builder.)
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Add Gesture to track the finger
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[self.view addGestureRecognizer:pan];
}
- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateChanged) {
CGPoint point = [gesture locationInView:self.view];
for (UIButton *button in [self.view subviews]) {
if ([button isKindOfClass:[UIButton class]]) {
if (button.tag == 1) {
button.highlighted = CGRectContainsPoint(button.frame, point);
} else if (button.tag == 2) {
button.highlighted = CGRectContainsPoint(button.frame, point);
} //
}
}
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
for (UIButton *button in [self.view subviews]) {
if ([button isKindOfClass:[UIButton class]]) {
button.highlighted = NO;
}
}
}
}
EDIT :
[[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanned:)];
- (void)handlePanned:(UIPanGestureRecognizer*)thePanner{
if (thePanner.state == UIGestureRecognizerStateChanged ){
//disable button
}else if (thePanner.state == UIGestureRecognizerStateEnded) {
//enable button
}else if ( thePanner.state == UIGestureRecognizerStateFailed ){
//enable button
}
}
You aren't checking to see if where you are touching is where a button is located.
Quickest solution I see is:
Create properties for each of your buttons, we'll call them button1, button2 and button3.
Create your panGestureRecognizer
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[self.view addGestureRecognizer:pan];
}
Your method to handle the pan:
-(void)handlePanGesture:(UIPanGestureRecognizer *)gesture
{
//create a CGpoint so you know where you are touching
CGPoint touchPoint = [gesture locationInView:self.view];
//just to show you where you are touching...
NSLog(#"%#", NSStringFromCGPoint(touchPoint));
//check your button frame's individually to see if you are touching inside it
if (CGRectContainsPoint(self.button1.frame, touchPoint))
{
NSLog(#"you're panning button1");
}
else if(CGRectContainsPoint(self.button2.frame, touchPoint))
{
NSLog(#"you're panning button2");
}
else if (CGRectContainsPoint(self.button3.frame, touchPoint))
{
NSLog(#"you're panning button3");
}
And that should be it.

Can I use scrollview.bounces property of webview for handling webview scroll?

I want to stop bounce in webview. can my app get rejected in appstore if I use following statement in my code?
self.viewController.webView.scrollView.bounces = NO;
Thanks!
if ([[[UIDeice currentDevice] SystemVersion] floatValue] >= 5.0)//iOS>=5.0
{
webView.scrollView.bounces = NO;
}
else//iOS<5.0
{
for (id subview in webView.subviews)
{
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).bounces = NO;
}
}
if (webView respondsToSelector:#selector(scrollView)]) {
webView.scrollView.bounces = NO;
} else {
for (id subview in webView.subviews) {
if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {
((UIScrollView*)subview).bounces = NO;
}
}
}

UIButton disappears when my application returns from running in the background

I have a small project that contains a few UITextFields with a number keypad. When the keyboard is displayed I'm adding a button as a subview for the user to dismiss the keyboard.
However, if the keyboard is active and I close the application, the button I've added will disappear upon relaunching the app. (The app stays inactive, through multitasking, and therefore not quit completely.)
This is the code im using to add the button (my "done" button configured in the xib).
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow)name:UIKeyboardWillShowNotification object:nil];
[super viewDidLoad];
}
- (void)keyboardWillShow{
[[NSNotificationCenter defaultCenter] removeObserver:self];
// We must perform on delay (schedules on next run loop pass) for the keyboard subviews to be present.
[self performSelector:#selector(addHideKeyboardButtonToKeyboard) withObject:nil afterDelay:0];
}
- (void)addHideKeyboardButtonToKeyboard{
// Locate non-UIWindow.
doneButton.hidden=NO;
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
if (!keyboardWindow) return;
// Locate UIKeyboard.
UIView *foundKeyboard = nil;
for (UIView __strong *possibleKeyboard in [keyboardWindow subviews]) {
// iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
if ([[possibleKeyboard description] hasPrefix:#"<UIPeripheralHostView"]) {
possibleKeyboard = [[possibleKeyboard subviews] objectAtIndex:0];
}
if ([[possibleKeyboard description] hasPrefix:#"<UIKeyboard"]) {
foundKeyboard = possibleKeyboard;
break;
}
}
if (foundKeyboard) {
[doneButton setImage:[UIImage imageNamed:#"doneupHeb.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:#"donedownHeb.png"] forState:UIControlStateHighlighted];
doneButton.frame = CGRectMake(-1, 163, 106, 53);
[foundKeyboard addSubview:doneButton];
// Add the button to foundKeyboard.
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
[loan resignFirstResponder];
[YearCycle resignFirstResponder];
[prime resignFirstResponder];
[MothlyReturn resignFirstResponder];
[doneButton removeFromSuperview];
doneButton = nil;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
textField.delegate=self;
//editingField = textField;
if ([prime isFirstResponder]||[MothlyReturn isFirstResponder]){
scroll.contentOffset = CGPointMake(0, 166 );
}
// if ([YearCycle isFirstResponder]){
// scroll.contentOffset = CGPointMake(0, 200);
}
- (IBAction)closeNumpad:(id)sender{
[loan resignFirstResponder];
[YearCycle resignFirstResponder];
[prime resignFirstResponder];
[MothlyReturn resignFirstResponder];
scroll.contentOffset = CGPointMake(0, 0);
doneButton.hidden=YES;
}
i fixed the problem with a little help from other questions in the website - for all of you that have or will have the problem - this is the code:
Please note: the button himself are designed in the xib file and not in the code.
the .h file:
BOOL firstTime;
BOOL add;
BOOL keyboardOpened;
IBOutlet UIButton *doneButton;
the .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
firstTime = TRUE;
add = TRUE;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; // Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
// [[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)addButtonToKeyboard {
// create custom button
/* UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:[UIImage imageNamed:#"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:#"DoneDown.png"] forState:UIControlStateHighlighted];
doneButton.tag = 3;
[doneButton addTarget:self action:#selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];*/
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[keyboard description] hasPrefix:#"<UIPeripheralHostView"] == YES && add){
doneButton.frame = CGRectMake(-1, 163, 106, 53);
[keyboard addSubview:doneButton];
}
}
}
- (void)removeButtonFromKeyboard
{
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, remove the button
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES) [[keyboard viewWithTag:3] removeFromSuperview];
}
}
- (IBAction)doneButton:(id)sender {
[loan resignFirstResponder];
[YearCycle resignFirstResponder];
[ageOfCeo resignFirstResponder];
[YearofBusiness resignFirstResponder];
scroll.contentOffset = CGPointMake(0, 0);
if (![[[UIDevice currentDevice] model] isEqualToString:#"iPad"] && ![[[UIDevice currentDevice] model] isEqualToString:#"iPad Simulator"])
{
[self removeButtonFromKeyboard];
firstTime = TRUE;
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
[theTextField resignFirstResponder];
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if ([ageOfCeo isFirstResponder]||[YearofBusiness isFirstResponder]){
scroll.contentOffset = CGPointMake(0, 166 );
}
// firstResponder = textField;
}
- (void)keyboardDidShow:(id)sender
{
if (![[[UIDevice currentDevice] model] isEqualToString:#"iPad"] && ![[[UIDevice currentDevice] model] isEqualToString:#"iPad Simulator"])
{
NSLog(#"%#",[[UIDevice currentDevice] model]);
[self addButtonToKeyboard];
keyboardOpened = TRUE;
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (![[[UIDevice currentDevice] model] isEqualToString:#"iPad"] && ![[[UIDevice currentDevice] model] isEqualToString:#"iPad Simulator"])
{
[self removeButtonFromKeyboard];
keyboardOpened = FALSE;
}
}
i think your problem because you are removing the observer in the - (void)keyboardWillShow .. try to put this line [[NSNotificationCenter defaultCenter] removeObserver:self]; in the -(void)viewDidUnload

NSStatusItem right click menu

I'm working on a status bar app that has a left and right click. I've got the start of this working by following the tips from other posts but I'm not sure how to go about showing a menu on right click.
I use a subclassed NSView as the custom view of my NSStatusItem and have the right and left clicks executing different functions:
- (void)mouseDown:(NSEvent *)theEvent{
[super mouseDown:theEvent];
if ([theEvent modifierFlags] & NSCommandKeyMask){
[self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}else{
[self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
}
}
- (void)rightMouseDown:(NSEvent *)theEvent{
[super rightMouseDown:theEvent];
[self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}
How can I show a menu on right click, the same way the standard NSStatusItem does on left click?
NSStatusItem popUpStatusItemMenu: did the trick. I am calling it from my right click action and passing in the menu I want to show and it's showing it! This is not what I would have expected this function to do, but it's working.
Here's the important parts of what my code looks like:
- (void)showMenu{
// check if we are showing the highlighted state of the custom status item view
if(self.statusItemView.clicked){
// show the right click menu
[self.statusItem popUpStatusItemMenu:self.rightClickMenu];
}
}
// menu delegate method to unhighlight the custom status bar item view
- (void)menuDidClose:(NSMenu *)menu{
[self.statusItemView setHighlightState:NO];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
// setup custom view that implements mouseDown: and rightMouseDown:
self.statusItemView = [[ISStatusItemView alloc] init];
self.statusItemView.image = [NSImage imageNamed:#"menu.png"];
self.statusItemView.alternateImage = [NSImage imageNamed:#"menu_alt.png"];
self.statusItemView.target = self;
self.statusItemView.action = #selector(mainAction);
self.statusItemView.rightAction = #selector(showMenu);
// set menu delegate
[self.rightClickMenu setDelegate:self];
// use the custom view in the status bar item
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
[self.statusItem setView:self.statusItemView];
}
Here is the implementation for the custom view:
#implementation ISStatusItemView
#synthesize image = _image;
#synthesize alternateImage = _alternateImage;
#synthesize clicked = _clicked;
#synthesize action = _action;
#synthesize rightAction = _rightAction;
#synthesize target = _target;
- (void)setHighlightState:(BOOL)state{
if(self.clicked != state){
self.clicked = state;
[self setNeedsDisplay:YES];
}
}
- (void)drawImage:(NSImage *)aImage centeredInRect:(NSRect)aRect{
NSRect imageRect = NSMakeRect((CGFloat)round(aRect.size.width*0.5f-aImage.size.width*0.5f),
(CGFloat)round(aRect.size.height*0.5f-aImage.size.height*0.5f),
aImage.size.width,
aImage.size.height);
[aImage drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}
- (void)drawRect:(NSRect)rect{
if(self.clicked){
[[NSColor selectedMenuItemColor] set];
NSRectFill(rect);
if(self.alternateImage){
[self drawImage:self.alternateImage centeredInRect:rect];
}else if(self.image){
[self drawImage:self.image centeredInRect:rect];
}
}else if(self.image){
[self drawImage:self.image centeredInRect:rect];
}
}
- (void)mouseDown:(NSEvent *)theEvent{
[super mouseDown:theEvent];
[self setHighlightState:!self.clicked];
if ([theEvent modifierFlags] & NSCommandKeyMask){
[self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}else{
[self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
}
}
- (void)rightMouseDown:(NSEvent *)theEvent{
[super rightMouseDown:theEvent];
[self setHighlightState:!self.clicked];
[self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}
- (void)dealloc{
self.target = nil;
self.action = nil;
self.rightAction = nil;
[super dealloc];
}
#end
One option is to just fake the left mouse down:
- (void)rightMouseDown: (NSEvent *)event {
NSEvent * newEvent;
newEvent = [NSEvent mouseEventWithType:NSLeftMouseDown
location:[event locationInWindow]
modifierFlags:[event modifierFlags]
timestamp:CFAbsoluteTimeGetCurrent()
windowNumber:[event windowNumber]
context:[event context]
eventNumber:[event eventNumber]
clickCount:[event clickCount]
pressure:[event pressure]];
[self mouseDown:newEvent];
}
Added little something for when you need title in your view
- (void)drawRect:(NSRect)rect{
if(self.clicked){
[[NSColor selectedMenuItemColor] set];
NSRectFill(rect);
if(self.alternateImage){
[self drawImage:self.alternateImage centeredInRect:rect];
}else if(self.image){
[self drawImage:self.image centeredInRect:rect];
} else {
[self drawTitleInRect:rect];
}
} else if(self.image){
[self drawImage:self.image centeredInRect:rect];
} else {
[self drawTitleInRect:rect];
}
}
-(void)drawTitleInRect:(CGRect)rect
{
CGSize size = [_title sizeWithAttributes:nil];
CGRect newRect = CGRectMake(MAX((rect.size.width - size.width)/2.f,0.f),
MAX((rect.size.height - size.height)/2.f,0.f),
size.width,
size.height);
NSDictionary *attributes = #{NSForegroundColorAttributeName : self.clicked?[NSColor highlightColor]:[NSColor textColor]
};
[_title drawInRect:newRect withAttributes:attributes];
}
- (void)statusItemAction {
NSEvent *event = NSApp.currentEvent;
if (event.type == NSEventTypeRightMouseDown || (event.modifierFlags & NSEventModifierFlagControl)) {
[self toggleMenu];
} else {
[self togglePopOver];
}
}