Jes*_*sus 7 macos cocoa focus nstextfield first-responder
我有一个的NSTextField的NSTableCellView里面,我想它告诉我的时候,我的NSTextField已经得到了禁用几个按钮的焦点事件,我发现这个方法:
-(void)controlTextDidBeginEditing:(NSNotification *)obj{
NSTextField *textField = (NSTextField *)[obj object];
if (textField != _nombreDelPaqueteTextField) {
[_nuevaCuentaActivoButton setEnabled:FALSE];
[_nuevaCuentaPasivoButton setEnabled:FALSE];
[_nuevaCuentaIngresosButton setEnabled:FALSE];
[_nuevaCuentaEgresosButton setEnabled:FALSE];
}
}
Run Code Online (Sandbox Code Playgroud)
但它会在我的文本字段开始编辑时触发,因为这样说,我希望在我关注textField时禁用按钮,而不是在我已经开始键入时
编辑:要根据Joshua Nozzi收到的帮助我的代码,它仍然无法正常工作
MyNSTextField.h
#import <Cocoa/Cocoa.h>
@class MyNSTextField;
@protocol MyNSTextFieldDelegate
@optional -(BOOL)textFieldDidResignFirstResponder:(NSTextField *)sender;
@optional -(BOOL)textFieldDidBecomeFirstResponder:(NSTextField *)sender;
@end
@interface MyNSTextField : NSTextField
@property (strong, nonatomic) id <MyNSTextFieldDelegate> cellView;
@end
Run Code Online (Sandbox Code Playgroud)
MyNSTextField.m
#import "MyNSTextField.h"
@implementation MyNSTextField
- (BOOL)becomeFirstResponder
{
BOOL status = [super becomeFirstResponder];
if (status)
[self.cellView textFieldDidBecomeFirstResponder:self];
return status;
}
- (BOOL)resignFirstResponder
{
BOOL status = [super resignFirstResponder];
if (status)
[self.cellView textFieldDidResignFirstResponder:self];
return status;
}
@end
Run Code Online (Sandbox Code Playgroud)
在我的viewcontroller EdicionDeCuentasWC.m上
#import "MyNSTextField.h"
@interface EdicionDeCuentasWC ()<NSTableViewDataSource, NSTableViewDelegate, NSControlTextEditingDelegate, NSPopoverDelegate, MyNSTextFieldDelegate>
@end
@implementation EdicionDeCuentasWC
#pragma mark MyNSTextFieldDelegate
-(BOOL)textFieldDidBecomeFirstResponder:(NSTextField *)sender{
NSLog(@"textFieldDidBecomeFirstResponder");
return TRUE;
}
-(BOOL)textFieldDidResignFirstResponder:(NSTextField *)sender{
NSLog(@"textFieldDidResignFirstResponder");
return TRUE;
}
#pragma mark --
@end
Run Code Online (Sandbox Code Playgroud)
在可视化编辑器中说,已经将我的所有NSTextFields更改为MyNSTextField类并将委托设置为我的文件所有者(EdicionDeCuentasWC)
我想我搞定了。我试图子类化NSTextFiled来覆盖becomeFirstResponder()and resignFirstResponder(),但是一旦我点击它,becomeFirstResponder()就会被调用并resignFirstResponder()在之后被调用。嗯?但是搜索字段看起来仍在编辑中,焦点仍在它上面。
我发现,当您单击搜索字段时,搜索字段将成为第一响应者,但NSText稍后会准备好,并且焦点将移至NSText.
我发现当NSText准备好时,它被设置为self.currentEditor(). 问题是 whenbecomeFirstResponder()的调用,self.currentEditor()还没有设置。所以becomeFirstResponder()不是检测它的焦点的方法。
另一方面,当焦点移到 时NSText,resignFirstResponder()将调用文本字段,您知道吗?self.currentEditor()已设置。所以,现在是告诉它的代表该文本字段获得焦点的时刻。
然后接下来,如何检测搜索字段何时失去焦点。再次,它是关于NSText. 然后,您需要监听NSText诸如 的委托方法textDidEndEditing(),并确保让它是超类来处理该方法并查看是否self.currentEditor()无效。如果是这种情况,则NSText失去焦点并告诉文本字段的委托。
我提供了一个代码,实际上是NSSearchField子类来做同样的事情。同样的原则也应该适用NSTextField。
protocol ZSearchFieldDelegate: NSTextFieldDelegate {
func searchFieldDidBecomeFirstResponder(textField: ZSearchField)
func searchFieldDidResignFirstResponder(textField: ZSearchField)
}
class ZSearchField: NSSearchField, NSTextDelegate {
var expectingCurrentEditor: Bool = false
// When you clicked on serach field, it will get becomeFirstResponder(),
// and preparing NSText and focus will be taken by the NSText.
// Problem is that self.currentEditor() hasn't been ready yet here.
// So we have to wait resignFirstResponder() to get call and make sure
// self.currentEditor() is ready.
override func becomeFirstResponder() -> Bool {
let status = super.becomeFirstResponder()
if let _ = self.delegate as? ZSearchFieldDelegate where status == true {
expectingCurrentEditor = true
}
return status
}
// It is pretty strange to detect search field get focused in resignFirstResponder()
// method. But otherwise, it is hard to tell if self.currentEditor() is available.
// Once self.currentEditor() is there, that means the focus is moved from
// serach feild to NSText. So, tell it's delegate that the search field got focused.
override func resignFirstResponder() -> Bool {
let status = super.resignFirstResponder()
if let delegate = self.delegate as? ZSearchFieldDelegate where status == true {
if let _ = self.currentEditor() where expectingCurrentEditor {
delegate.searchFieldDidBecomeFirstResponder(self)
// currentEditor.delegate = self
}
}
self.expectingCurrentEditor = false
return status
}
// This method detect whether NSText lost it's focus or not. Make sure
// self.currentEditor() is nil, then that means the search field lost its focus,
// and tell it's delegate that the search field lost its focus.
override func textDidEndEditing(notification: NSNotification) {
super.textDidEndEditing(notification)
if let delegate = self.delegate as? ZSearchFieldDelegate {
if self.currentEditor() == nil {
delegate.searchFieldDidResignFirstResponder(self)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您将需要更改NSSerachField为ZSearchField,并且您的客户端类必须符合ZSearchFieldDelegatenot NSTextFieldDelegate。这是一个例子。当用户单击搜索字段时,它会扩展其宽度,而当您单击其他位置时,通过更改NSLayoutConstraintInterface Builder 设置的值,搜索字段会失去焦点并缩小其宽度。
class MyViewController: NSViewController, ZSearchFieldDelegate {
// [snip]
@IBOutlet weak var searchFieldWidthConstraint: NSLayoutConstraint!
func searchFieldDidBecomeFirstResponder(textField: ZSearchField) {
self.searchFieldWidthConstraint.constant = 300
self.view.layoutSubtreeIfNeeded()
}
func searchFieldDidResignFirstResponder(textField: ZSearchField) {
self.searchFieldWidthConstraint.constant = 100
self.view.layoutSubtreeIfNeeded()
}
}
Run Code Online (Sandbox Code Playgroud)
这可能取决于操作系统的行为,我在 El Capitan 10.11.4 上尝试过,并且成功了。
代码也可以从 Gist 复制。 https://gist.github.com/codelynx/aa7a41f5fd8069a3cfa2
我有一个NSTextField重写-becomeFirstResponder和的自定义子类-resignFirstResponder。它的-cellView属性需要符合声明的协议-textDidBecome/ResignFirstResponder:(NSTextField *)sender,但这足以让您了解总体思路。它可以轻松修改为发布通知,您的控制器可以注册为观察者。我希望这有帮助。
- (BOOL)becomeFirstResponder
{
BOOL status = [super becomeFirstResponder];
if (status)
[self.cellView textFieldDidBecomeFirstResponder:self];
return status;
}
- (BOOL)resignFirstResponder
{
BOOL status = [super resignFirstResponder];
if (status)
[self.cellView textFieldDidResignFirstResponder:self];
return status;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8647 次 |
| 最近记录: |