Complete Noob question regarding NSTextField and delegate methods

Discussion in 'Mac Programming' started by Sidespin, Jun 26, 2008.

  1. Sidespin macrumors newbie

    Jun 25, 2008
    Hi everyone, I'm just starting out in Cocoa development, and having some trouble making a basic calculator application. Basically, I have an NSTextField in which the user types an equation they would like solved.

    I really want to intercept/remap keystrokes made by the user into the NSTextField. So if the user types a 'u' character, I want it to come out as a '4' a la a virtual numeric keypad (if that makes sense). I basically want to remap some keys. I also want to intercept some other keystrokes such as the arrow keys.

    For the arrow keys, I've managed to implement the control:TextView:DoCommandBySelector, which seems to work fine (even though I don't quite know what's going on). But for the keys with actual character values, I just can't seem to get it to work.

    After a lot of googling, I think I'm supposed to use

    - (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString

    delegate method, but this doesn't work for me. In this case, I don't even know what the replacementString and affectedCharRange variables represent. Do I just ignore them? I'm not sure this is even what I want though - I just want a simple key remap.

    Plus, this function appears to apply to an NSTextView, not an NSTextField - I think there's some overlap between these two classes, but it's all just serving to confuse me. I've also played around with other methods, such as insertText, but I don't quite know what I'm doing exactly.

    Is it just me or is Apple's documentation really hard to understand? I can't get a hold on this at all, and I've been at it for hours. If anyone can give me some pointers or a link to some code examples, it would be greatly appreciated. Thanks in advance, guys! Please go easy, I'm just starting out :)

    I'm on Tiger/XCode 2 if it makes any difference...
  2. RobCurie macrumors newbie

    Jun 26, 2008
    I totally agree that the Apple documentation is hard to understand. At first, at least. I actually came to the forums right now to post my own similar question about finding the right delegate method.

    You said you have a NSTextField, but the delegate you tried to use is from NSTextView. Why don't you try a NSTextField delegate, such as –textDidBeginEditing: or –textDidChange:. If I were you, I'd send NSLogs from each of them just to see how they work, and then to remap, maybe send a setObjectValue: (or whatever type you're using) message to the object in question.
  3. Sidespin thread starter macrumors newbie

    Jun 25, 2008
    Thanks a lot for your reply! I'll have a look at those delegate methods.

    I think that the delegate -controlTextDidBeginEditing may be the right way to go, but it's still doing my head in. It's all very confusing, not least that the xcode internal documentation hyperlinks seem to continually send me to the wrong (but very similarly named) method..! Does this happen for anyone else? :mad:

    I'll keep plugging away in the meantime! Any more help would be most welcome!
  4. Catfish_Man macrumors 68030


    Sep 13, 2001
    Portland, OR
    iirc you're right; there's a similar one on NSTextField that sounds more promising, but the control one is the one you want.
  5. Sidespin thread starter macrumors newbie

    Jun 25, 2008
    Thanks Catfish Man, but I'm still confused(!)

    Can anyone give me any more help? I'm no closer to working things out :(

    I'm not sure which delegate method I should be using -controlTextDidBeginEditing, endEditing, didChange, or maybe I should be attacking it through the field editor...?
  6. RobCurie macrumors newbie

    Jun 26, 2008
    If you don't know which delegate to implement, why not implement all of them?

    As long as you set the delegate to an object in the init method, you can use whatever delegate method for that object, including multiple methods.

    So just implement -controlTextDidBeginEditing, endEditing, and didChange, and differentiate each one with a simple NSLog message. Then, build and run the application, fiddle with it and see how each delegate responds by looking at the console.

    That should give you insight on how each delegate works, and you may find the one you're looking for. If not, at least you'll know that it's not an NSTextField delegate you're looking for.

    Hope you find it.
  7. aLoC macrumors 6502a

    Nov 10, 2006
    Maybe you could override keyDown: on your view. Here is a function from an old program of mine where I caught certain keys and mapped them to buttons. There might be a cleaner way to do it.

    - (void)keyDown:(NSEvent *)event
        //NSLog(@"Keypress in table");    
        NSString *keyString = [event charactersIgnoringModifiers];
        unichar firstChar = [keyString characterAtIndex:0];
        if ( firstChar == NSDeleteFunctionKey ) {
            //NSLog(@"You pressed del");
            [[self delegate] deleteAction:self]; // withConfirmation:YES];
        } else if ( firstChar == 0x000d ) {
            //NSLog(@"You pressed enter");
            [[self delegate] doubleClickOnTable:self];
        } else if ( firstChar == 0xf702 ) {
            //NSLog(@"You pressed left arrow");
            [[self delegate] parentButtonClicked:self];
        } else if ( firstChar == 0xf703 ) {
            //NSLog(@"You pressed right arrow");
            [[self delegate] doubleClickOnTable:self];
        } else {
            ////NSLog(@"First char was %0.4x", firstChar);   
            [super keyDown:event];
        //[self interpretKeyEvents:[NSArray arrayWithObject:event]];
  8. Sidespin thread starter macrumors newbie

    Jun 25, 2008
    A process of elimination, eh? I like it :)

    Sure beats my current programming technique of staring at the screen... :p I've come to the conclusion that none of those NSTextField delegates really do the job, so far as I can see, so overriding keyDown seems to be more promising.

    Unfortunately, I managed to set up the subclassed NSTextField and reconnected the outlets, but my(aLoc's) keyDown method doesn't seem to ever get called. Is there any obvious reason why that might be the case?

    Thanks so much for the help guys, this programming business is driving me crazy!
  9. newb16 macrumors regular

    Feb 27, 2008
    Did you look at NSCell's setFormatter:NSFormatter method ? Its delegate methods are called on each key event (i'm not sure about arrows)
  10. Sidespin thread starter macrumors newbie

    Jun 25, 2008
    Sorry newb16, I don't really understand how the formatter works - I couldn't even find the delegate methods you were referring to in the documentation...

    I decided to leave this problem for a while, and work on some other stuff, seeing as I'm not getting very far with it. I'm still at the beginner stage after all. I was hoping this would really be a trivial sort of problem, but maybe it's just me being slow. Anyway, thanks everyone for all your help :)

    If anyone does know the correct way to approach this or better yet, can find some sample code, it would be great!

Share This Page