UIScrollView scrollRectToVisible: animated: not counted on iOS7

[self.scrollView scrollRectToVisible:rect animated:YES]; 

Does anyone know why this works fine on iOS6.1, and on iOS7.0.4 it always scrolls to the UITextField, which became the first Responder, no matter what type 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 the lowest level, when the keyboard is displayed due to the UITextField inside the UIScrollView, it became the first responder on iOS6.1, but on iOS7.0.4 it scrolls so that UITextFiled is displayed instead.

As I understand it, UIScrollView in the iOS7 SDK no matter what, autoscrolls everything that became the first responder inside it when scrollRectToVisible: is called: animated :.

+8
ios objective-c iphone ios7 uiscrollview
source share
4 answers

I suspect most of your developers use scrollRectToVisible:Animated: in conjunction with system keyboard notifications, as described in Apple Docs here . For me, the sample code provided by Apple did not work (well, only half did it).

Entering a method call inside the send block fixed the problem for me:

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

I don’t quite understand why this works, and I’m not sure that it is 100% safer, but on the other hand, it feels much safer than just delaying the call for 0.1 seconds, as suggested in another answer Rikkles .

I'm not an expert on streaming issues (yet), but it seems like any hidden system method overrides the scroll behavior already in the main queue when sending UIKeyboardDidShowNotification . Therefore, if we put our method call in the main queue, it will be executed later and for this will give the desired effect. (But this is only an assumption.)

+9
source share

In iOS 8 (and possibly 7), the OS automatically switches to UITextField at the end of the runloop operation, just before it returns to listening to user input. I did not find any way to log in after autoscrolling the OS and before user input. Neither UIKeyboardWillShowNotification nor UIKeyboardDidShowNotification will work with hooks.

However, what will always work is a good old trick when executing a selector after a delay. Just enter the scroll code in your own method and call this method as follows:

 - (void)keyboardDidShow:(NSNotification*)aNotification { // ... all code to choose the view you want ... [self performSelector:@selector(moveToView:) withObject:visibleView afterDelay:0.1]; } - (void)moveToView:(UIView *)aView { [self.scView scrollRectToVisible:aView.frame animated:YES]; } 

And it will start after autoscrolling the OS, and you will be gold.

+8
source share

I met this problem before. Not easy, but boring for sure.

That was because I set contentSize to 0 (because you don't want it to scroll). And you must set at least 1.

 [scrollView setContentSize: CGSizeMake(1, self.view.frame.size.height)]; 

I hope this is a solution;)

+4
source share

I found a solution to this problem, but it is not very pretty. To scroll to the right place, you must register for both the WillShow keyboard notifications and the DidShow keyboard notifications. Then, the code for installing scrollview attachments is placed in the keyboardWillShowNotification observer selector, and the code for scrolling to the right place is placed in the keyboardDidShowNotification observer selector. Here is what I have:

Inside viewDidLoad:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; 

Notification Methods:

 - (void) keyboardWillShow: (NSNotification*) aNotification; { NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; float kbHeight = kbSize.height < kbSize.width ? kbSize.height : kbSize.width; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbHeight, 0.0); _scrollView.contentInset = contentInsets; _scrollView.scrollIndicatorInsets = contentInsets; } -(void)keyboardDidShow:(NSNotification*)notification { CGRect aRect = CGRectMake(0, 0, _scrollView.frame.size.width, _scrollView.frame.size.height - _scrollView.frame.origin.y - self.scrollView.contentInset.bottom); CGRect scrollFrame = CGRectMake(self.loginView.frame.origin.x + self.loginButton.frame.origin.x, self.loginView.frame.origin.y + self.loginButton.frame.origin.y, self.loginButton.frame.size.width, self.loginButton.frame.size.height); if (!CGRectContainsRect(aRect, scrollFrame)) { [_scrollView scrollRectToVisible:scrollFrame animated:YES]; } } 
+1
source share

All Articles