0

How can I make an NSComboBox disappear when an NSTextField is clicked? This is the code I'm using:

Class comboBox: (used as custom class for my NSComboBox in the interface builder) comboBox.h:

#import <Cocoa/Cocoa.h>
@interface comboBox1 : NSComboBox
-(void)Hide;
@end

comboBox.m:

#import "comboBox1.h"
@implementation comboBox1
-(void)Hide
{
    [self setHidden:YES];
}
@end

Class txtField: (used as custom class for my NSTextField in the interface builder) txtField.h:

#import <Cocoa/Cocoa.h>
@interface txtField1 : NSTextField
@end

txtField.m:

#import "txtField1.h"
#import "comboBox1.h"
@implementation txtField1
-(void)mouseDown:(NSEvent *)theEvent
{
    comboBox1 *obj = [[comboBox1 alloc] init];
    [obj Hide];
}
@end

But it doesn't work: when click the TextField nothing happens. Thank you in advice.

rambodrahmani
  • 99
  • 4
  • 12

2 Answers2

0

You can use delegate methods for NSTextfield

 - (void)controlTextDidBeginEditing:(NSNotification *)obj;
 - (void)controlTextDidEndEditing:(NSNotification *)obj;
 - (void)controlTextDidChange:(NSNotification *)obj;

update

Apple provides documentation and examples for NSTrackingAreas.

- (void) viewWillMoveToWindow:(NSWindow *)newWindow {
    // Setup a new tracking area when the view is added to the window.
    NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:[textfield frame] options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void) mouseEntered:(NSEvent*)theEvent {
    // Mouse entered tracking area.
}

- (void) mouseExited:(NSEvent*)theEvent {
    // Mouse exited tracking area.
}
NewStack
  • 990
  • 8
  • 19
  • Thank you man! there is a problem: I want the NSComboBox to appear as soon as the user clicks the NSTextField. With the code you provided instead the NSComboBox appears when the user starts writing (editing) the content of the NSTextField. Any solutions for this? – rambodrahmani Mar 06 '13 at 15:35
0

Your mouseDown: method is the culprit here. Instead of referencing to the comboBox1 in your NIB, you create a new instance of comboBox1 every time and tell that new instance to 'hide'. Next to leaking memory there, you probably don't want a new comboBox1 every time you click the NSTextField.

Instead use NSTextField's delegate methods to get what you want.

- (void)controlTextDidBeginEditing:(NSNotification *)obj;
- (void)controlTextDidEndEditing:(NSNotification *)obj;
- (void)controlTextDidChange:(NSNotification *)obj;

Since you're using IB I assume you got a View- or WindowController with both the txtField1 and the comboBox1. In your ViewController (or WindowController) set the ViewController as the NSTextField's delegate and tell the comboBox1 to hide in one of the delegate methods.

An example:

In your ViewController.h first declare both objects:

@property (assign) IBOutlet comboBox1 *comboBox1;
@property (assign) IBOutlet txtField1 *txtField1;

Then in your implementation:

- (void)controlTextDidBeginEditing:(NSNotification *)obj {
    [comboBox1 hide];
}

Just don't forget to connect the outlets to your ViewController in Interface Builder. Also connect the delegate outlet of the txtField1 to your Viewcontroller.

Gerald Eersteling
  • 1,244
  • 14
  • 28
  • Thank you man! Now finally the NSComboBox in my NIB appears but there is a problem: I want it to appear as soon as the user clicks the NSTextField. With the code you provided instead the NSComboBox appears when the user starts writing (editing) the content of the NSTextField. Any solutions for this? – rambodrahmani Mar 06 '13 at 15:35
  • And one more question, you said: Since you're using IB I assume you got a View- or WindowController with both the txtField1 and the comboBox1. I don't have such a thing. – rambodrahmani Mar 06 '13 at 15:36
  • @rambodrahmani There are different options available to let the NSComboBox appear when you click the txtField1. The easiest would be in the `mouseDown:` method of the txtField1 you were already using. Implement a new method in the txtField1's `delegate`. In that method do the same as you did in `-(void)controlTextDidBeginEditing:(NSNotification *)obj`. Next in the txtField1's `mouseDown:` invoke that method on the `delegate` – Gerald Eersteling Mar 06 '13 at 15:59
  • @rambodrahmani I assumed you were using a View- or WindowController, it could be any other class however. – Gerald Eersteling Mar 06 '13 at 16:05
  • I did what you told me but I got the same original problem: nothing happens. In my NSTextField Delegate I create the method: -(void)changeVisibility { NSLog(@"Check"); [mycombo1 setHidden:NO]; } In the mouseDown: event of my NSTexField I wrote: txtField1Delegate *TFD = [[txtField1Delegate alloc] init]; [TFD changeVisibility]; What happens is that in the console it writes "Check" but my NSComboBox won't appear! – rambodrahmani Mar 06 '13 at 16:18
  • I declared the two IBOutlets un my NSTextField delegate like this: `@property (assign) IBOutlet NSTextField *mytxtField;` `@property (assign) IBOutlet NSComboBox *mycombo1;` – rambodrahmani Mar 06 '13 at 16:22
  • In your `mouseDown:` you need to invoke the message on the existing instance of your NSTextField delegate. Simply put, in your `mouseDown:` the call `[self.delegate changeVisibility]` should suffice. – Gerald Eersteling Mar 07 '13 at 08:33
  • Yes, it worked! But I have one last question, I wrote `[self.delegate changeVisibility]` in my NSTextField `mouseDown` event and there is a warning saying `Instance method '-changeVisibility' not found`. Do you know why? – rambodrahmani Mar 07 '13 at 11:30
  • The problem was just that I had to use `_delegate` instead of `self.delegate`. Thank you man so much for your support! – rambodrahmani Mar 07 '13 at 13:14
  • No problem, glad I could help. And to respond to your question: The warning tells you that the compiler could not find the method `-changeVisibility` in your `delegate`'s interface, which could lead to an exception (crash) when invoked. In this particular case however, you know that the method DOES exist. To silence the warning you should declare the method `-changeVisibility` in the `delegate`'s interface. This makes the method available to other classes, including your textfield (assuming you are importing the comboBox's interface). – Gerald Eersteling Mar 07 '13 at 13:54