Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 选择焦点上NSTEXT字段的文本_Cocoa_Select_Focus_Nstextfield - Fatal编程技术网

Cocoa 选择焦点上NSTEXT字段的文本

Cocoa 选择焦点上NSTEXT字段的文本,cocoa,select,focus,nstextfield,Cocoa,Select,Focus,Nstextfield,有谁能建议一种方法,当用户单击NSTextField时,选择它的所有文本 我确实找到了将NSTextField子类化的建议,然后使用mouseDown或firstResponder,`但这超出了我的技能范围。因此,我希望有一个更简单的解决方案,或者有人愿意详细说明所需的步骤。没有更简单的解决方案,您需要子类化NSTextField来做您想要做的事情。如果要在Cocoa中做任何有用的事情,您需要学习如何处理子类化 文本字段对子类来说可能相对复杂,因为NSTextField使用称为字段编辑器的单独N

有谁能建议一种方法,当用户单击
NSTextField
时,选择它的所有文本


我确实找到了将
NSTextField
子类化的建议,然后使用
mouseDown
firstResponder
,`但这超出了我的技能范围。因此,我希望有一个更简单的解决方案,或者有人愿意详细说明所需的步骤。

没有更简单的解决方案,您需要子类化
NSTextField
来做您想要做的事情。如果要在Cocoa中做任何有用的事情,您需要学习如何处理子类化

文本字段对子类来说可能相对复杂,因为
NSTextField
使用称为字段编辑器的单独
NSTextView
对象来处理实际编辑。此文本视图由
NSWindow
对象为
NSTextField
返回,并重新用于页面上的所有文本字段

与任何
nsrresponder
子类一样,
NSTextField
响应方法
-acceptsFirstResponder
-becomeFirstResponder
。当窗口希望为特定控件或视图提供焦点时,将调用这些控件或视图。如果从这两种方法返回
YES
,则控件/视图将具有first responder状态,这意味着它是活动控件。但是,如前所述,当单击时,NSTextField实际上会给出字段编辑器的第一响应者状态,因此您需要在
NSTextField
子类中执行类似操作:

@implementation MCTextField
- (BOOL)becomeFirstResponder
{
    BOOL result = [super becomeFirstResponder];
    if(result)
        [self performSelector:@selector(selectText:) withObject:self afterDelay:0];
    return result;
}
@end

这首先调用超类的
-becomeFirstResponder
实现,它将完成管理字段编辑器的艰苦工作。然后它调用
-selectText:
,选择字段中的所有文本,但它会在延迟0秒后执行此操作,这将延迟到下一次运行事件循环。这意味着选择将在字段编辑器完全配置后进行。

使用Swift进行一些更新:

import Cocoa

class TextFieldSubclass: NSTextField {
    override func mouseDown(theEvent: NSEvent) {
        super.mouseDown(theEvent)
        if let textEditor = currentEditor() {
            textEditor.selectAll(self)
        }
    }
}
或用于精确选择:

import Cocoa

class TextFieldSubclass: NSTextField {
    override func mouseDown(theEvent: NSEvent) {
        super.mouseDown(theEvent)
        if let textEditor = currentEditor() {
            textEditor.selectedRange = NSMakeRange(location, length)
        }
    }
}

Swift版本,适合我:

import Cocoa

class TextFieldSubclass: NSTextField {
    override func becomeFirstResponder() -> Bool {
        let source = CGEventSourceCreate(CGEventSourceStateID.HIDSystemState)
        let tapLocation = CGEventTapLocation.CGHIDEventTap
        let cmdA = CGEventCreateKeyboardEvent(source, 0x00, true)
        CGEventSetFlags(cmdA, CGEventFlags.MaskCommand)
        CGEventPost(tapLocation, cmdA)
        return true
    }
}

来自@Rob的答案可能在某一点上有效,但正如@Daniel所指出的,它不再有效。看起来Cocoa想要跟踪鼠标并拖出一个选择来响应单击,而尝试选择文本来响应
becomeFirstResponder
则不太适合

然后,需要拦截鼠标事件以防止跟踪。通过反复试验,我找到了一个似乎在OS X 10.10上运行的解决方案:

@interface MyAutoselectTextField : NSTextField
@end

@implementation MyAutoselectTextField
- (void)mouseDown:(NSEvent *)theEvent
{
    [[self currentEditor] selectAll:nil];
}
@end
据我所知,在调用
mouseDown:
时,字段编辑器已经设置好,可能是
成为第一响应者的副作用。调用
selectAll:
,然后选择字段编辑器的内容。相反,在
self
上调用
selectText:
不起作用,可能是因为设置了字段编辑器。请注意,此处的
mouseDown:
覆盖不会调用
super
super
将运行一个跟踪循环,该循环将拖出一个选择,我们不希望出现这种行为。请注意,一旦文本字段成为第一响应者,此
mouseDown:
覆盖不会影响选择,因为此时调用的是字段编辑器的
mouseDown:


我不知道这适用于什么范围的OSX版本;如果你在乎的话,你需要测试一下。不幸的是,使用
NSTextField
总是有点脆弱,因为字段编辑器的工作方式非常奇怪,因此依赖于
super

中的实现细节。我喜欢Konstantin的解决方案,但每次按下鼠标都会选择它。以下是我在
mouseDown
方法中选择的一个变体,但前提是它刚刚成为第一响应者:

class SelectingTextField: NSTextField {

    var wantsSelectAll = false

    override func becomeFirstResponder() -> Bool {
        wantsSelectAll = true

        return super.becomeFirstResponder()
    }

    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)

        if wantsSelectAll {
            selectText(self)
            wantsSelectAll = false
        }
    }
}

我知道这是一个老问题,但这里有一个更新为那些谁可能会绊倒在这个问题上

重写NSTextField并挂接到becomeFirstResponder()。您不必担心管理委托或单击。棘手的部分是先找到聚焦文本字段的字段编辑器,然后再要求它选择所有文本

目标-C

//在autoselectionfocustextfield.h中
@接口AutoselectOnFocusTextField:NSTextField
@结束
//在autoselectionfocustextfield.m中
@实现AutoselectOnFocusTextField
-(BOOL)成为第一反应者{
如果(![super becomeFirstResponder]){
返回否;
}
NSText*fieldEditor=[self-currentEditor];
如果(字段编辑器!=nil){
[fieldEditor performSelector:@selector(selectAll:)with object:self afterDelay:0.0];
}
返回YES;
}
@结束
Swift

类AutoselectOnFocusTextField:NSTextField{
重写func becomeFirstResponder()->Bool{
超级守卫,成为第一反应者{
返回错误
}
如果let editor=self.currentEditor(){
编辑器。执行(#选择器(selectAll(:)),带:self,afterDelay:0)
}
返回真值
}
}

非常感谢,它工作得很好,让我学到了一些东西。我根据您提供的代码创建了.m文件,.h文件如下:#import@interface MCTextField:NSTextField{}@end,在interface Builder中,我进入file->Read Class file,选择了MCTextField.h,然后我将文本字段的类更改为MCTextField。这也是许多常规问题的解决方案“以编程方式选择文本-例如,NSTextView中的文本选择例程如果在很多情况下直接调用,则无法正确启动,您需要将它们放入PerformSelect:afterDelay:0调用中。这在10.9SDK中似乎不起作用。当我点击该字段时,我会得到一个闪烁的插入符号,除非我延迟很长时间,比如1秒。正如@DanielWabyick所指出的,这个解决方案不再有效。我刚刚发布了一个新的answe