views:

5328

answers:

7

I have 6 UITextFields on my UIScrollView. Now, I can scroll by user request. But when the keyboard appear, some textfields are hidden.

That is not user-friendly. How scroll programatically the view so I get sure the keyboard not hide the textfield?

+1  A: 

If you set the delegate of your text fields to a controller object in your program, you can have that object implement the textFieldDidBeginEditing: and textFieldShouldReturn: methods. The first method can then be used to scroll to your text field and the second method can be used to scroll back.

You can find code I have used for this in my blog: Sliding UITextViews around to avoid the keyboard. I didn't test this code for text views in a UIScrollView but it should work.

Matt Gallagher
A: 

Mmm ok. Thank you.

I put this on a scroll view and get crazy from the middle and forward. I suspect is because is being build a new view each time, rigth?

I still need to figure how move the scrollview similar to how the user do it. Howerver your code is usefull because the calculation (that part I never will be figure by me ;) )

mamcx
+1  A: 

I found this function:

scrollRectToVisible

I think is the way to go. The previous answer clip the view...

mamcx
A: 

I found from this:

http://forums.macrumors.com/showthread.php?t=577273

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    /* scroll so that the field appears in the viewable portion of screen when the keyboard is out */

    UIScrollView* v = (UIScrollView*) self.view ;
    CGPoint pt ;
    if {
     CGRect rc = [textField bounds];
     rc = [textField convertRect:rc toView:v];
     CGPoint pt = rc.origin ;
     pt.x = 0 ;
     pt.y -= 60 ;
     [v setContentOffset:pt animated:YES];  
    }

    return;
}

Work half. Everything move ok but as reported in that thread can't tap in a field up from the current :(.

I can't find a single solution that work just fine...

mamcx
+4  A: 

Finally, a simple fix:

UIScrollView* v = (UIScrollView*) self.view ;
CGRect rc = [textField bounds];
    rc = [textField convertRect:rc toView:v];
rc.origin.x = 0 ;
rc.origin.y -= 60 ;

rc.size.height = 400;
[self.scroll scrollRectToVisible:rc animated:YES];

Now I think is only combine this with the link above and is set!

mamcx
A: 

I have a partial solution to this, right now I achieved to smoothly scroll the uitextfields when you bring the keyboard up. But when you hide the keyboard, they just snap back to position. Everything is detailed here:

http://www.iphonesampleapps.com/2009/12/adjust-uitextfield-hidden-behind-keyboard-with-uiscrollview/

Bottom line you can do this by implementing the keyboard notifications, calculate the size of the view, resize de scroll view when the keyboard shows up and do the same when it hides.

In the article I explain this in detail and also there is a sample application you can download and test by yourself.

muanis
+7  A: 

Here's what worked for me. Having an instance variable that holds the value of the UIScrollView's offset before the view is adjusted for the keyboard so you can restore the previous state after the UITextField returns:

//header
@interface TheViewController : UIViewController <UITextFieldDelegate> {
    CGPoint svos;
}


//implementation
- (void)textFieldDidBeginEditing:(UITextField *)textField {
    svos = scrollView.contentOffset;
    CGPoint pt;
    CGRect rc = [textField bounds];
    rc = [textField convertRect:rc toView:scrollView];
    pt = rc.origin;
    pt.x = 0;
    pt.y -= 60;
    [scrollView setContentOffset:pt animated:YES];           
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [scrollView setContentOffset:svos animated:YES]; 
    [textField resignFirstResponder];
    return YES;
}
Cirrostratus
Just a minor addition: Put svos = scrollView.contentOffset; in the ViewDidLoad method if you have multiple UITextFields. Because if you go from one text field to the next without hiding the keyboard svos will be overwritten and therefore restoring the content offset will fail.
Volker Voecking
In my case I did not want to restore the offset present when the view first loads, but just before each individual UITextField is accessed.
Cirrostratus