Anyway to make a (wrapping) NSTextField write a ca

2019-04-10 20:22发布

问题:

I want to use a wrapping text field that can potentially contain carriage returns in my app. Is there any way to force the NSTextField object to write a carriage return into the text area instead of sending its action to its target when the Return key is pressed?

回答1:

This is covered in Technical Q&A QA1454, which also enumerates reasons why one would use NSTextField instead of NSTextView in this case.

You can implement the following method in the text field delegate:

- (BOOL)control:(NSControl*)control
    textView:(NSTextView*)textView
    doCommandBySelector:(SEL)commandSelector
{
    BOOL result = NO;

    if (commandSelector == @selector(insertNewline:))
    {
        // new line action:
        // always insert a line-break character and don’t cause the receiver
        // to end editing
        [textView insertNewlineIgnoringFieldEditor:self]; 
        result = YES;
    }

    return result;
}


回答2:

Okay, I figured out one way to do it, but this very well may not be the best (or even a good) way. I subclassed NSTextField, and overrode -textShouldEndEditing: like so:

-(BOOL)textShouldEndEditing:(NSText *)textObject {
    NSEvent * event = [[NSApplication sharedApplication] currentEvent];
    if ([event type] == NSKeyDown && [event keyCode] == 36) {
        [self setStringValue:[[self stringValue] stringByAppendingString:@"\n"]];
        return NO;
    }
    else {
        return [super textShouldEndEditing:textObject];
    }
}


回答3:

I found a combination of Sean and Bevarious worked best for me. Sean's answer assumes that the new line is always wanted to be added to the end (instead of for instance where the user's cursor is placed).

-(BOOL)textShouldEndEditing:(NSText *)textObject 
{
    NSEvent * event = [[NSApplication sharedApplication] currentEvent];
    if ([event type] == NSKeyDown && [event keyCode] == 36) 
    {
        [textObject insertNewlineIgnoringFieldEditor:nil];
        return NO;
    }
    else 
    {
        return [super textShouldEndEditing:textObject];
    }
}


回答4:

Swift version:

override func textShouldEndEditing(textObject: NSText) -> Bool {
    let event = NSApplication.sharedApplication().currentEvent
    if event?.type == NSEventType.KeyDown && event?.keyCode == 36 {
        self.stringValue = self.stringValue.stringByAppendingString("\n")
        return false
    } else {
        return super.textShouldEndEditing(textObject)
    }
}