The way I do it is the view my fields are on is a scrollview with a normal contentsize(320x480). When the user selects a textbox to type in I change the context size to it's now longer, I use scrollToRect to move the textbox to the top of the view and then I disable user interaction for the scrollview so they can't actually scroll around. When they close the keyboard I reverse the changes.
__________________ Super Pig iOwn - Inventory anything and everything.
Connect:
- The view outlet to your 'main' view (not the scrollview!)
- The textFields' delegates to your viewController
- The scrollView Outlet to your Scrollview
In the implementation you have to add the following delegate methods:
Code:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(@"preparing to show keyboard");
scrollView.frame = CGRectMake(0,44,320,200); //44:NavigationBar ; 200: Keyoard
[scrollView scrollRectToVisible:textField.frame animated:YES]; //Oddly enough, it only works with the animation...
}
I'm implementing this exact feature at the moment and I've run into a problem.
Say there are 6 UITextField objects on screen. When I resize the frame and the keyboard displays, there are maybe a maximum of 3 UITextFields visible in the new resized view. The scrolling and everything works fine, but the problem is that the remaining 3 fields which aren't visible while the keyboard is up all clear their contents when the keyboard disappears again.
Hope that makes sense. Does anyone know what this might be caused by?
One of the things I have on my to do list is how to handle a scrollable set of text fields-- think a customer's:
sold to: ....
bill to: ...
ship to: .....
I have these layed-out so that they are on a single, vertically-scrollable view.
When the user touches a text field, the kb pops up and:
1) if the kb does not cover the touched field, this is fine (for now)
2) if the kb covers the touched field, this is bad, but the user can manually scroll to make it visible
3) I plan to add some code so the display will automatically scroll so that the field touched in 2 is above the kb (prolly vertically centered).
I don't particularly like the choices for 2 & 3 as both might confuse the user.
The iPhone mobile safari browser handles this problem in a more intuitive way:
It adds a submenu above the keyboard that has buttons for previous, next and done.
This essentially provides the tab and back-tab keys that are missing from the kb
It gives the user an intuitive way to tab (forward or back) through a lot of text fields.
IMO, Apple should provide this tab-key menu (and functionality) as an option... but they don't.
Also, there doesn't seem to be an easy way to programatically determine the sequence and position of the various text fields so I can write some generalized code to tab/scroll between fields.
The only way I can think to do this is parse the xib file and extract the frame, kb type, etc, info for the text fields, then write my own tab submenu. While not too difficult, this is a pita!
I came up with a less sophisticated approach for a recent app. I have a label that is normally hidden that resides in the upper half of the screen. You can't see it, but when you try to type in a text field it becomes visible and it echoes what the user types. It's sub-optimal in that it looks totally different than a text field, but it works ok.
I can move the view around using a scroll view. But what I can't do is make the user actually able to scroll around himself. I'd like to give the user the option to scroll up to a different field to edit.
So when a textfield or textview are touched the screen scrolls up automatically as the keyboard comes in from bottom.
However I have a problem!
I have a textfield at the top of the screen that does not require the screen to be scrolled up when keyboard appears but below that I have a textview that does need the screen scrolling up.
I cannot figure out how to check in the methods which control triggered the notification and process accordingly?
I have tried passing the name of the objects in the addObserver calls but the no notifications occur!
Is there a way to query which control is current selected on the screen?
So when a textfield or textview are touched the screen scrolls up automatically as the keyboard comes in from bottom.
However I have a problem!
I have a textfield at the top of the screen that does not require the screen to be scrolled up when keyboard appears but below that I have a textview that does need the screen scrolling up.
I cannot figure out how to check in the methods which control triggered the notification and process accordingly?
I have tried passing the name of the objects in the addObserver calls but the no notifications occur!
Is there a way to query which control is current selected on the screen?
Yeah, NSNotification.object returns the object associated with the notification. So you can simply check if the object is one or more of the fields you dont want to autoscroll for.
So when a textfield or textview are touched the screen scrolls up automatically as the keyboard comes in from bottom.
However I have a problem!
I have a textfield at the top of the screen that does not require the screen to be scrolled up when keyboard appears but below that I have a textview that does need the screen scrolling up.
I cannot figure out how to check in the methods which control triggered the notification and process accordingly?
I have tried passing the name of the objects in the addObserver calls but the no notifications occur!
Is there a way to query which control is current selected on the screen?
You probably figured this out long ago in your own way, but what i did was i just made if blocks around the code and duplicated it in each statement. So i have two buttons, the first on i say if [UItextfield isFirstResponder]{}
then else if [UItextfield2 isFirstResponder] {//make it animate up and then down}
My problem with this is that when I click on one textfield, then on the other without clicking done on the keyboard, it will not animate up for the first one, then just animate down when i leave the second textfield. Is there a way to just set the screen back to original? I'm actually going to try and make it so that on the animation which moves things back to normal, i just put in the original perameters of the screen (just came up with it as i was typing). So i will set the y back to what it should be to make the screen sit in its place.
//this is what i put in and it moves the screen back to its original place.
//it is not +=, but just = now
rect.origin.y = 0;
Last edited by Moe2392; 09-01-2011 at 11:17 AM.
Reason: adding what i did.