在 NSSearchField 上按下功能键而无需子类化

发布于 2024-11-04 09:48:21 字数 606 浏览 1 评论 0 原文

我有一个简单的应用程序,其中有一个 NSSearchField,我想知道用户是否按下了例如箭头键。我不想子类化,因为我想修改应用程序中 IBOutlet 的值,但无法在子类中执行此操作。

编辑

我在 NSSearchField 子类中重写的 keyUp: 方法是:

-(void)keyUp:(NSEvent*)event
{
    if ([event keyCode]==36){
    customers* c= [[customers alloc] init];//customers is the class where i have my IBOulets and my methods
    [[self window] selectKeyViewFollowingView:self];// change the first responder
    [c searcht:[self stringValue]];//here i want to call a method to make a query and change the stringValues of some IBOulets
    }
}

I have a simple application which has an NSSearchField and I want to know if the user presses, for example, an arrow key. I don't want to subclass, because I want to modify the values of the IBOutlets in my aplication, and I can't do that in a subclass.

EDIT

The keyUp: method that I override in my NSSearchField subclass is:

-(void)keyUp:(NSEvent*)event
{
    if ([event keyCode]==36){
    customers* c= [[customers alloc] init];//customers is the class where i have my IBOulets and my methods
    [[self window] selectKeyViewFollowingView:self];// change the first responder
    [c searcht:[self stringValue]];//here i want to call a method to make a query and change the stringValues of some IBOulets
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

別甾虛僞 2024-11-11 09:48:21

将您的控制器指定为搜索字段的委托并实现该方法:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command

然后您应该能够接收简单的 NSResponder 选择器,例如与箭头键相对应的 moveDown:、moveUp:、moveLeft:、moveRight:。

Assign your controller as the delegate of your searchfield and implement the method:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command

You should then be able to receive simple NSResponder selectors such as moveDown:, moveUp:, moveLeft:, moveRight: which correspond to the arrow keys.

旧梦荧光笔 2024-11-11 09:48:21

NSSearchField 继承自 NSControl,它具有您正在寻找的委托方法。

- (void)controlTextDidChange:(NSNotification *)aNotification

将 NSSearchField 设置为您的委托并实现此方法。可能需要运行检查以确保是您的 NSSearchField 开始编辑。也许您可以使用 FirstResponder。类似于:

- (void)controlTextDidChange:(NSNotification *)aNotification {
    If (mySearchField.isFirstResponder) {
        //throwdown
    }
}

http://developer.apple.com/library/mac/#documentation/cocoa/reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/cl/NSControl

NSSearchField inherits from NSControl which has the delegate method you are looking for.

- (void)controlTextDidChange:(NSNotification *)aNotification

Set the NSSearchField as your delegate and implement this method. Might want to run a check to make sure it's your NSSearchField that's started editing. Maybe you could use FirstResponder. Something like:

- (void)controlTextDidChange:(NSNotification *)aNotification {
    If (mySearchField.isFirstResponder) {
        //throwdown
    }
}

http://developer.apple.com/library/mac/#documentation/cocoa/reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/cl/NSControl

半衬遮猫 2024-11-11 09:48:21

无法获取已传递给您没有代码的视图的 NSEvent。如果要更改视图或控件的键处理行为,则必须进行子类化。您也许可以在响应者链中的搜索字段之前插入另一个对象,获取事件,执行您想要的任何操作,然后就像您没有处理它一样,并将其传递到字段……只是我脑海中的一个疯狂的想法。

更新回复您的keyUp:代码:

好的,问题正在变得清晰。当您在代码中创建新的 customer* 对象时,您还必须在代码中连接它的连接。他们没有为你连接。您实际上并没有为此使用 IBOutlets,而只是使用常规的旧 ivars。 IBOutlets 的存在只是为了让您可以在 Interface Builder 的图形界面中连接对象。我不知道你到底想在 searcht: 中做什么,但举个例子,如果你想更改文本字段的内容:

- (void)searcht:(NSString *)theString {

    // Do some stuff with the string

    [myTextField setStringValue:someResultString];

}

其中 customer.h 看起来像:

@interface customer : NSObject {
    IBOutlet NSTextField * myTextField;
}

这不会执行任何操作,包括不发出警告,因为 myTextFieldnil。您可以整天调用 nil 上的方法,但什么也不会发生。您需要做的是为 customer 对象提供一个指向文本字段的指针;这不应该是 IBOutlet。您可以在 init... 方法中执行此操作,或者直接设置它(请注意,这意味着搜索字段必须有到文本字段的连接才能将其传递)到 Customer,这可能是理想的,也可能不是。):

@interface Customer : NSObject {
    NSTextField * myTextField;
}

@property NSTextField * myTextField;    // Note: does not need to be retained.
@end

#import "Customer.h"

@implementation Customer

@synthesize myTextField;

- (id)initUsingTextField:(NSTextField *)tf {

    if( !(self = [super init]) ) {
        return nil;
    }

    myTextField = tf;

    return self;
}

@end

*顺便说一句,Obj-C 中的传统类名以大写字母开头:“Customer”,而不是“customer”。

There's no way to get the NSEvents that have already been handed to a view whose code you don't have. If you want to change the key-handling behavior of a view or control, you have to subclass. You might be able to insert another object before the search field in the responder chain, get the event, do whatever you want, and then act like you didn't handle it and pass it on to the field...just a wild thought from the top of my head.

UPDATE in reply to your keyUp: code:

Okay, the problem is becoming clear. When you create that new customer* object in code, you also have to hook up its connections in code. They're not connected for you. You don't actually use IBOutlets for this, just regular old ivars. IBOutlets are only there so that you can connect objects in the graphical interface of Interface Builder. I don't know exactly what you're trying to do in searcht:, but just as an example, if you wanted to change the contents of a text field:

- (void)searcht:(NSString *)theString {

    // Do some stuff with the string

    [myTextField setStringValue:someResultString];

}

Where customer.h looks something like:

@interface customer : NSObject {
    IBOutlet NSTextField * myTextField;
}

This will do nothing, including give no warning, because myTextField is nil. You can call methods on nil all day long and nothing will happen. What you need to do is give the customer object a pointer to the text field; this should not be an IBOutlet. You could do this in an init... method, or just by setting it directly (note that this means that the search field will have to have a connection to the text field in order to pass it on to the Customer, which may or may not be desirable):

@interface Customer : NSObject {
    NSTextField * myTextField;
}

@property NSTextField * myTextField;    // Note: does not need to be retained.
@end

#import "Customer.h"

@implementation Customer

@synthesize myTextField;

- (id)initUsingTextField:(NSTextField *)tf {

    if( !(self = [super init]) ) {
        return nil;
    }

    myTextField = tf;

    return self;
}

@end

*As an aside, conventionally class names in Obj-C start with uppercase letters: "Customer", not "customer".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文