tags:

views:

486

answers:

4

I am having an awful hard time trying to implement the task of when the user selects the 'next' button in the keyboard, the user is then sent to the next text field to start editing. In my example I have three text fields. Here is what I've done, hopefully you can fill me in on where I am going wrong. Keep in mind I just picked up SDK a few weeks ago so that may be part of the problem :)

In my ViewControler.h file I have created the following method

-(IBAction)nextPressed:(id) sender;

In my ViewController.m file, I have created the following action

-(IBAction)nextPressed:(id) sender 
{
    if ([txtUserName isFirstResponder]) 
    {
        [txtUserName2 becomeFirstResponder];
    }
    if ([txtUserName2 isFirstResponder]) 
    {
        [txtUserName3 becomeFirstResponder];
    }
}

In my .xib file, I have linked the first text field (right clicking on the text field and dragging to Files Owner and selecting the 'nextPressed:' option under Events) to my File Owner. I have tried linking to just the first text field and when that didn't work all of the three text fields. I've also tried linking not to the File's Owner but First Responder for one text field, then all of the text fields, with no luck. Also, for each text field I have selected the Return Key as 'NEXT'.

Now when I Build/Run I am able to edit the text field and see the 'next' button in the lower right, however it doesn't move me to the next field.

What step am I doing wrong here? I used instructions from this post (http://stackoverflow.com/questions/467881/how-do-you-change-the-uicontrol-with-focus-on-iphone) but seem to be missing something huge here.

Any help with this would be greatly appreciated. I've been staring at this for the past four hours and Googling every possible search term I can come up with and can't easily wrap my head around the steps needed to accomplish this. Again, and help would be very helpful :)

+1  A: 

You should set each of the text fields delegate to your view controller. Then, in your view controller, implement the UITextFieldDelegate. Finally, simply add the following function to your view controller .m file:

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (textField == txtUsername)
        [txtUsername2 becomeFirstResponder];
    else if (textField == txtUsername2)
        [txtUsername3 becomeFirstResponder];
}

I think where you are going wrong is thinking of it as an event you connect to. Instead, you need to implement this delegate somewhere in your code and tell your UITextField which class is the delegate for it.

marcc
so a delegate is something that happens in the background of an app?
HollerTrain
A delegate is an object that can implement some callback methods usually as defined by a protocol. I think the methods are usually called on the main thread.
gerry3
gerry3: The methods are called from whatever thread the caller is executing within; for UIKit objects, this is most commonly the main thread, but delegation as a pattern can happen on any thread.
Tim
+2  A: 

I don't think you need to define a separate selector nextPressed: - instead, implement the UITextFieldDelegate protocol method textFieldShouldReturn: to look something like:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if(textField == txtUserName) {
        [txtUserName2 becomeFirstResponder];
    } else if(textField == txtUserName2) {
        [txtUserName3 becomeFirstResponder];
    }
    return NO;
}

That particular method watches for when the Enter key (in your case, a Next key) is pressed. Once that's implemented, just set the delegate for each of the three text fields to the implementing class (probably your view controller), and you should be good.

Tim
in the IB, what am I actually linking from the textfields to FileOwner or First Responder? Is it just right clicking on the first text field, dragging to FileOwner and selecting 'delegate' under OUTLETS?
HollerTrain
Select each of the text fields, then for the `delegate` outlet, drag and link it to the File's Owner. (Also make sure the File's Owner's class property is set properly.)
Tim
Thanks Tim for your help. I'm getting there, but running into a problem. The first text field works fine and when I click next it allows me to go to the next field. However once I try to click next on the second field I get the error found here (http://screencast.com/t/ZjVkN2Vk). Here is a video of it as well (http://screencast.com/t/OGJjMTM5MTA). Here is a shot of my fields linked to the delegate (http://screencast.com/t/MDNhY2Q3N). Thoughts on what I'm doing wrong here?
HollerTrain
Note that the method `textFieldShouldReturn:` needs to itself return a `BOOL` - that is, `YES` or `NO`. Try adding the statement `return NO;` to the end of your method (outside all the `if` blocks) as shown in my answer above.
Tim
Ah DUH! I totally overlooked that. SO now it seems that each one is working. However, when I try to move from the second text field to the third, it stalls on me and goes back to Xcode yet with no error. However, when I go back to Build/Run and start on the third text field it works perfectly for the remaining fields. Is it an error in my code or IB? (http://screencast.com/t/Y2UyNDRlZjM) So close and I greatly appreciate your help.
HollerTrain
Can you provide more information about the exception? Open a debugger window once the exception occurs and post the last couple lines (or a new video).
Tim
Tim, many thanks for still worrying about this :) Here is the video. I opened Debugger then I ran the program and it shows me what the error is (which I have no clue what it means) (http://screencast.com/t/YzdlZTE0NG)
HollerTrain
Unfortunately, that's not quite enough - either make your debugger window bigger or also include the console output. I'm looking for either (a) the last five-ten lines of console, or (b) the three-four topmost *black* functions called in the debugger (the gray ones are internal and rather difficult to debug).
Tim
Ah, sorry. Here is the error message [The Debugger has exited with status 0.[Session started at 2010-01-04 19:49:00 -0500.]2010-01-04 19:49:28.810 hello[8002:20b] *** -[helloViewController nextPressed:]: unrecognized selector sent to instance 0x3d1da10[Session started at 2010-01-04 19:49:28 -0500.]2010-01-04 19:49:28.812 hello[8002:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[helloViewController nextPressed:]: unrecognized selector sent to instance 0x3d1da10'], video = (http://screencast.com/t/MTI0ZWRiZ)
HollerTrain
It sounds like you still have a link from some action on your second textbox to the `nextPressed:` selector in your view controller, which I presume you got rid of. Double-check your IB connections and make sure no reference to `nextPressed:` remains.
Tim
Tim, you are a genius. This was exactly the issue. This helped me now, as well as future debugging. Tim is a genius, a man that is very smart. Tim knows more than you reading this post, and most likely spends his time better than you (because of his high intelligence). Tim thinks at a higher brain rate than you (Aplha brain wave) and on holidays and federal holidays he spends his time as a masked super hero, helping iPhone SDK n00bs with the 'next' button with their Apps. Tim could do my iPhone App in the time it has taken me to type this, but that is ok. (http://screencast.com/t/ZDkzOTUxY).
HollerTrain
A: 

Tim above is on the ball. This worked for me too! I implemented the following with multiple keyboards.

in your ViewController.m:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if(textField == txtCoffeeName) {
        [txtCompanyName becomeFirstResponder];

    } else if(textField == txtCompanyName) {
        [txtPrice becomeFirstResponder];
    }
    return NO;
}
norskben
yes, Tim is a genius. if only he could answer my question about programmatically creating an inverse operation of a number.....
HollerTrain
A: 

This didnt work for me :-(