Question

I kind of expected this to be the default behaviour for the NSTextField to automatically respond to left/right arrow key with caret movement. Unfortunately, in my app this does not happen. Is there an option to turn that behaviour on or do I have to add it myself?

To explain further, the interface is generated dynamically. I have views (xibs that contain NSTextFields) and their view controllers that I stack up (manually) on another view. When a view is created (that is, its controller (newView)) I use this code to add it to my NSBox's contentView (boxContent):

[boxContent addSubview:[newView view]];
[newView setWithLabel:attributeLabel forProperty:attribute];
newViewY -= [[newView view] frame].size.height;
[[newView view] setFrameOrigin:NSMakePoint(0, newViewY)];
newViewY -=padding;

Weird thing is that text input and backspace work while other keys (arrows, delete) do not.

Is this perhaps a problem with the NSResponder chain? Why does text input work then?

Was it helpful?

Solution

So, I do not know what is the cause of these problems, but this is the roundabout solution I made.

I created a subclass of NSTextField that sends commands (selectors) to its NSTextView. NSTextField has one subview and that subview has yet another subview that is actually the NSTextView:

NSTextView* textView = nil;    
NSArray* subs = [self subviews];
if( subs && [subs count] > 0 ){
    NSView* firstView = [subs objectAtIndex:0];
    NSArray* firstSubs = [firstView subviews];
    if (firstSubs && [firstSubs count] > 0) {       
        textView = [firstSubs objectAtIndex:0];
    }
}

When I initialise that one (if anyone knows a better way than this subview search, please tell), I send it the commands that it was supposed to get:

-(void)keyUp:(NSEvent *)theEvent{   
   BOOL isShift = (theEvent.modifierFlags & NSShiftKeyMask) > 0;
   BOOL isCommand = (theEvent.modifierFlags & NSCommandKeyMask ) > 0;
   switch (theEvent.keyCode) {
      case 7: if( isCommand && !isShift ) [self notifyTextView:@selector(cut:)]; break;
      case 8: if( isCommand && !isShift ) [self notifyTextView:@selector(copy:)]; break;
      case 9: if( isCommand && !isShift ) [self notifyTextView:@selector(paste:)]; break;
      case 123: [self notifyTextView:isShift ? @selector(moveLeftAndModifySelection:) : @selector(moveLeft:)];break;
      case 124: [self notifyTextView:isShift ? @selector(moveRightAndModifySelection:) :@selector(moveRight:)];break;
      case 117: [self notifyTextView:@selector(deleteForward:)];break;
      default: break;
   }
   [super keyUp:theEvent];
}

Might not be the most elegant solution, but it works (until I figure out what went wrong in the first place).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top