UIScrollView scrollRectToVisible:animated: not taking rect into account on iOS7

ios, ios7, iphone, objective-c, uiscrollview

Solution

I suspect that most of you developers are using `scrollRectToVisible:Animated:` in conjunction with system keyboard notifications as explained in the Apple Docs here. For me the sample code provided by Apple didn't work (well, only half of it did).

Putting the method call inside a dispatch block fixed the problem for me:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.scrollView scrollRectToVisible:rect animated:YES];
});

I don't fully understand why this works and I'm not sure if this is 100% safe but on the other hand it feels a lot safer than just delaying the call by 0.1 seconds as suggested in another answer by Rikkles.

I'm not an expert on threading issues (yet) but it seems like whatever hidden system method is overriding the scrolling behavior is already on the main queue when the `UIKeyboardDidShowNotification` is sent. So if we put our method call on the main queue as well it will be executed afterwards and therefor yield the desired effect. (But that's only a guess.)

Problem

``` [self.scrollView scrollRectToVisible:rect animated:YES]; ``` Does anyone have a clue of why this works perfectly fine on iOS6.1 and on iOS7.0.4 always scrolls to the UITextField that has become firstResponder no matter what kind of rect I send as an argument? ``` CGRect rect = CGRectMake(0, self.scrollView.frame.size.height - 1, 320, 1); [self.scrollView scrollRectToVisible:rect animated:YES]; ``` This code will scroll the UIScrollView to its bottom when the keyboard is showed due to a UITextField inside the UIScrollView has become first responder on iOS6.1 but on iOS7.0.4 it is scrolled so that the UITextFiled is visible instead. As I figure this, the UIScrollView in the iOS7 SDK no matter what, autoscrolls to whatever has become the first responder inside of it when scrollRectToVisible:animated: is called.

Original source