Is there a way to close the NSComboBox popup programmatically?
There seem to be a bug with NSComboBox when the popup is open, and the control get's removed and then released. For some reason, the dealloc of the NSComboBox doesn't clear the popup before destructing.
Edit: Just to clarify - this bug only happens when the popup list is opened. Otherwise the control is released properly and cleanly.
Edit Edit:
This is how to reproduce it.
Create a new Cocoa application.
Turn off automatic reference counting.
In #(applicationDidFinishLaunching) create a new NSComboBox and store it to a member.
Add the combo box to the window's contentView.
Create a new menu item with a keyboard shortcut and bind to a selector.
In the menu item's selector: remove the combo box from the view and release the member. Don't forget to set it back to nil.
Run the application.
Click on the combo box to show the popup up.
Use the shortcut to remove the combo box.
You can perform a check in your code or grey out menu items by using the NSComboBox delegate methods -comboBoxWillPopUp: and -comboBoxWillDismiss: to control a BOOL.
The BOOL property can be used to control enabling of the menu item.
Set the delegate of the combo box.
To the interface of the delegate add
#property BOOL itemEnabled;
and to the implementation add
- (void)comboBoxWillPopUp:(NSNotification *)notification {
self.itemEnabled = NO;
}
- (void)comboBoxWillDismiss:(NSNotification *)notification {
self.itemEnabled = YES; //re-enabled when dismissed
}
Set initial value of itemEnabled to YES.
In the xib bind the Enabled attribute of the menu item to the delegate and the Model Key Path set to self.itemEnabled
Related
I would like to disable the Application "menu highlight" that happens when you press a shortcut key assigned to an NSMenuItem that belongs to the specific menu in question.
The issue is that in the application you use the keyboard quite a bit and having the menus becoming highlighted all the time becomes a bit annoying but I still want to have the menus (including the shortcuts) there as it shows the user which actions that can be used.
Declare a custom NSMenuItem subclass and start using that custom class instead of NSMenuItem.
In this class you should override this method:
- (BOOL)isHighlighted
{
return NO;
}
This way you will not have the menu item highlighted.
EDIT
Try this:
[item setOnStateImage: item.offStateImage];
FFR: Look up the following methods in the docs:
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
Will work for both selecting the menu item and the associated command key.
Within your NSDocument provide a body for validateMenuItem
such as,
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
SEL theAction = [menuItem action];
if (theAction == #selector(openPreferencesPanel:)) {
return !_isCurrentlyModal; //A BOOL in MyDocument
}
return [super validateMenuItem:menuItem]; // Keep this for proper cut, paste, etc validation
}
In your case, the above selector might be highlight:. Check the nib/xib and inspect it. It might be attached to the First Responder. Copy the method name.
Also have a gander at for more general items (buttons, etc) and also includes menu items.
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem
I have an NSComboBox. I've set an action selector. When the box gets hidden the selector fires, even if the user never touched it. Yes, I need to hide it.
IBOutlet NSComboBox *comboBox;
[comboBox setAction:#selector(onComboBoxSelection:)];
- (void)onComboBoxSelection:(id)sender
{
NSLog(#"Why does this fire twice");
//My code doesn't actually set hidden here, it's just for proof while debugging the issue.
[comboBox setHidden:YES];
}
Why would hiding an NSControl fire it's selector? What's the best way to fix it?
Update:
I've fixed it by wrapping the method. But I'd still like to understand why, or other ways to fix it.
- (void)onComboBoxSelection:(id)sender
{
if(![sender isHidden]{
NSLog(#"Now only fires once");
//My code doesn't actually set hidden here, it's just for proof while debugging the issue.
[comboBox setHidden:YES];
}
}
Set a breakpoint in onComboBoxSelection: and look at the backtrace when it's called the second time (type bt in the debugger to see the backtrace). That will explain what's going.
A combo box is both a text field and a popup, and it will fire actions for both. The text field action is fired when editing ends, either by hitting the Return key or when it resigns first responder (e.g., tabbing out to another field).
When you hide the combo box, the text field resigns first responder and fires its action.
What you probably want to do is check if combo box value has actually changed, and only then proceed with hiding the combo box, etc.
Another option is to use data bindings to observe changes to the combo box. Bind the combo box value to a property on your controller. Then implement the property setter in your controller.
try this [comboBox setHidden:1];
here is the low down:
-(IBAction)button1click:(id)sender;
{
label1.hidden=YES;
textfield1.hidden=YES;
label2.hidden=NO;
textfield2.hidden=NO;
-(IBAction)button2click:(id)sender;
{
label1.hidden=NO;
textfield1.hidden=NO;
label2.hidden=YES;
textfield2.hidden=YES;
the is issue is that when i first open my screen all 4 labels are visible. By default button1 radio is checked but label2 and textfield 2 are visible when they shouldnt be. if i press button1 even though it is already selected the items with hide and then all is good. My issue is having them hidden when the screen first opens up.
Thanx all for you help
You can, in your viewDidLoad method:
-(void) viewDidLoad
{
[super viewDidLoad];
[self button1click:nil]; //nil or the instance of button1 if you need it
}
In this way, you will execute the same code when you press button1 without duplicate your code.
You can take one of two approaches to hide the label.
a) in Interface builder you can click the check box for hidden in the attributes inspector. If you do that the default behavior will always be hidden when the app launches then you can make it visible in code like your example shows
b) add your existing code to hide the label to your view controllers - (void)viewDidLoad method.
both methods work equally well.
When you create that objects you can set foo.isHidden = YES
I have a view with a nssearchfield a nstableview and a nsmatrix with three radiobuttons. Using delegates i change the selected radiobutton when the searchfield is the firstresponder and the user press tab, that works perfectly but what i want is that the searchfield don't loose the firstresponder when the user press tab
You can sub class NSSearchField and add this function
- (BOOL)resignFirstResponder {
return NO;
}
It will refuse to relinquish first responder status.
Another way is catch the windowDidUpdate notification. These are sent whenever anything changes, including change of focus, so you can check for the firstResponder and make it become first responder again.
[searchField becomeFirstResponder];
I have a menu with several items created in interface builder. It looks fine there and 'enabled' is checked. But when I run the application, all menu items are grayed out.
I've checked isEnabled, it returns true.
Also, menu items created programmatically (with initWithTitle and without interface builder) work just fine.
Am I missing something here? I'm really quite new to OS X development.
Remember to set your menu item's target and ensure that said target implements the menu item's action method.
menuItem.target = self;
If the menu item’s target is set, then NSMenu first checks to see if that object implements the item’s action method. If it does not, then the item is disabled. If the target does implement the item’s action method, NSMenu first checks to see if that object implements validateMenuItem: or validateUserInterfaceItem: method. If it does not, then the menu item is enabled. If it does, then the enabled status of the menu item is determined by the return value of the method.
If the menu item’s target is not set and the NSMenu object is not a contextual menu, then NSMenu uses the responder chain to determine the target. If there is no object in the responder chain that implements the item’s action, the item is disabled.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html
In case somebody might google this out and benefit, 'Action' method was declared without :(id)sender parameter:
-(IBAction) quit;
Strangely, setAction method in NSMenuItem ate it and didn't complain. Oh well.
Ah, the plague of using NSMenu...
Check out <NSMenuValidation>.
Usually the implementation will be as simple as:
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
return [menuItem isEnabled];
}