Make NSComboBox Appear when NSTextField is clicked

2019-08-27 23:15发布

问题:

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.

回答1:

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.



回答2:

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.
}