How would you make a Button display a Menu when clicked? - objective-c

I am looking for some code to make a Menu appear next to a button when it is clicked.
What code would I need for this?
Sorry if this sounds a bit vague.

Why not use NSPopUpButton?

NSPopupButton was my first thought as well. It's how apps with the "action gear" buttons accomplish their menus.
If you do have something else in mind though, look at NSMenu's +popUpContextMenu:withEvent:forView:. Just hook an action method up to your button, create an NSMenu and populate it with NSMenuItems, and send it to this method along the the current event from NSApplication's currentEvent getter.

If you really need to roll this yourself, rather than using one of the built-in controls that shows a menu, you can create an NSPopupButtonCell and use that to show the NSMenu:
NSPopUpButtonCell *popupCell = [[NSPopUpButtonCell alloc] initTextCell:#"" pullsDown:YES];
[popupCell setMenu:yourMenu];
[popupCell trackMouse:event inRect:[yourButton bounds] ofView:yourButton untilMouseUp:YES];
[popupCell release];
You'd want to adjust the pullsDown:, inRect:, and ofView: arguments as necessary to position the menu the way you want.

Related

UIActionSheet - add disabled button

Is there a way to add a disabled (non-clickable, greyed out) button to a UIActionSheet?
All I see is "addButtonWithTitle" which does not supply any properties to work with.
I believe there is no way to add disabled button in a UIActionSheet. From the class reference:
Use the UIActionSheet class to present the user with a set of
alternatives for how to proceed with a given task. You can also use
action sheets to prompt the user to confirm a potentially dangerous
action. The action sheet contains an optional title and one or more
buttons, each of which corresponds to an action to take.
If the button is disabled, it should not be added into the UIActionSheet in the first place since it is not an alternative on how to proceed with a given task.
UIActionSheet's interface doesn't really give you much control over appearance of the the whole view or the buttons.
You can use some other libraries. If you can't find one that gives such control, it would be simple to you to add that functionality. For example JLActionSheet or RDActionSheet.
You can also, try to retrieve the subviews of UIActionSheet by traversing the view stack recursively. self.view.subviews or by [[UIApplication sharedApplication].windows[0].subviews] "try both, I don't know which one is the right one". You can find the views using introspection, and find the button you want to disable.

Is there any way to highlight the status bar item programmatically?

I'd like to perform the following:
when I click on the status bar item (NSStatusItem) I want to highlight it (no menu) indefinitely and when the application loses focus I want to stop highlighting it.
Is there any way of doing this? I can't find it, tbh.
You can probably do this with a custom view that sends the status item a drawStatusBarBackgroundInRect:withHighlight: message.
I doubt there's any way to do it without a custom view, since, as I mentioned in my comment on the question, keeping the item highlighted when the user doesn't have the mouse down on it looks bad.
Old question, but I think it is worth adding this alternative answer.
This will not automatically un-highlight when the application loses focus, but this allows you to highlight without using a custom view (as the other answer requires):
NSStatusItem *statusItem = [self getStatusItem];
[statusItem.button setHighlighted:YES];
You can unhighlight it manually using the same method:
[statusItem.button setHighlighted:NO];
Note I got this answer from a similar question here.

Selecting text programmatically in menu view

I write an "Agent" Cocoa app where I have TextField in status icon's menu, it looks like this:
(source: ifotos.pl)
And in couple of places I select its contents programmatically (e.g. in -(BOOL)becomeFirstResponder of my NSTextField subclass)
And it doesn't work. It surely has something to do with the fact that it's in menu, not in window. But how do I fix that?
Because your view is in a menu, it's possible that the textfield isn't responding because the run loop is not in its default mode. Try calling selectText: like this:
[textField performSelector:#selector(selectText:) withObject:nil
afterDelay:0.0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
Why don't you just use a window instead? Menus are implemented as windows under the hood: you can do the same thing, just position and style your window appropriately.
Edit: answer largely rewritten

Have UIButton showDetails take in an argument

I have many UIButton elements on my MKMapView. When the user clicks on a button I get a showDetails notification. But how do I tell which button the user clicked on? The only hack I know of is to pass in the tag value which is an integer. Surely there must be a more elegant way. I tried subclassing UIButton but since it is a cluster, I cannot subclass it and use all of theUIButtons existing functionality.
Thanks
Deshawn
tag is a good way to identify you can also use current title to differentiate if all buttons have different titles. here is a code snippet
[[button currentTitle] isEqualToString:#"your desired string"];
But I prefer use tags.

NSTableView responding to first click in a panel

I have noticed in the Interface Builder if I want to click on or drag from the Library panel, I only have to click on it once, even if the Library panel does not have the current focus.
I am trying to build a panel that behaves similarly.
Is there any simple way to let the NSTableView accept the click, even if the window does not have the focus?
Thanks.
Ok, I found the answer. Inside from awakeFromNib I call this:
[self setBecomesKeyOnlyIfNeeded:YES];
It seems to do the trick. It's a little bit different from Interface Builder where the Panel actually gets the focus simultaneously with a single click, but doing it this way is just what I was looking for.
Your view should override -acceptsFirstMouse: to return YES (or evaluate the event passed to you to determine what to return). You'll have to subclass NSTableView to do that of course.