Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwanted automatic scrolling with UIScrollView and UITextFields as subviews

The "too long; didn't read" version: Is there any way to disable the automatic scrolling behaviour of UIScrollView when telling a UITextField to becomeFirstResponder?

I have a scroll view with paging enabled and several views as subviews, each subview being controlled by its own view controller. Each subview has a UITextField.

The requirement is that when a page is scrolled into view, it's text field should become first responder.

This is fine when using finger swipes to scroll -- I use the scroll view delegate method scrollViewDidEndDecelerating: to know when scrolling stops and a page is in view, I can tell the text field to become first responder.

However, when the scroll view is "autoscrolled", as in when telling the scrollview to scrollRectToVisible:animated:, the scroll view delegate method for deceleration isn't called. I use this method when scrolling newly created pages into view without the user's interation, or when the user taps the UIPageControl.

My solution was to simply set the first responder status of the text field before telling it to scroll into view - but it seems that telling a text field that is in a scroll view to become first responder causes the scroll view to automatically scroll it into view.

I assume this is behaviour used when putting text fields in table view cells (since table views are scroll view subclasses). If you set up a small test app, with a table view, and a text field within a table cell, if the keyboard would obscure the table view cell when it becomes first responder, the table view will automatically scroll it to be visible.

I don't understand, though, why this behaviour occurs in my example, where I'm not using a table view - just a plain scroll view.

I should also mention that my scroll view has vertical scrolling disabled and only scrolls horizontally.

I have tested in another test app that puts text fields as direct subviews of a scrollview (no view controllers or container views) and the same happens. If you tell a text field that is offscreen to become first responder, the scroll view with automatically scroll it for you.

This wouldn't normally be a problem, but it seems to screw up the paging of the scroll view. When I scroll with my finger, each view bounces and is centred properly. But when I scroll a rect to be visible with animation and tell a text field to become first responder, scroll view seems to become conflicted with itself and the view is only scrolled part of the way into view, and isn't centred.

Then, if I touch a view using my finger (not swipe, or even move), the scroll view jumps back to the first page.

My current work around for all this silly auto scrolling behaviour is to use an NSTimer to determine when to update the first responder.

I do the manual scrolling in code using scrollRectToVisible:animated and then after 0.3 seconds, call my method to update the text field to be first responder. (0.3 seconds was trial and error, trying to see which seemed to be the smallest amount of time to allow for the animation but still be long enough not to cause the conflict with the scrollview.

As you can see, this isn't elegant, and is likely to break.

Is there any way to disable the automatic scrolling behaviour of UIScrollView when telling a UITextField to becomeFirstResponder?

like image 632
Jasarien Avatar asked Jun 29 '10 11:06

Jasarien


1 Answers

Call becomeFirstResponder, then right away, set the contentOffset of the scrollview to its current position..

[textField becomeFirstResponder]; [scrollview setContentOffset:scrollview.contentOffset animated:NO]; 
like image 119
user353877 Avatar answered Oct 07 '22 13:10

user353877