9
votes

When the keyboard was hidden, the scrollview should back to it's origin contentInset, but it's not working in iOS7. Setting scrollview's contentInset when keyboard was shown is working but when the keyboard was hidden, the scrollview's contentInset can't set to inset zero. The code:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:Nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasHidden:) name:UIKeyboardDidHideNotification object:nil];
}

- (void)keyboardWasShown:(NSNotification *)notif
{
    CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);


    UIScrollView *scrollView = (UIScrollView *)self.view;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    CGRect rect = self.view.frame;
    rect.size.height -= keyboardSize.height;
    if (!CGRectContainsPoint(rect, self.wishContentField.frame.origin)) {
        CGPoint point = CGPointMake(0, self.wishContentField.frame.origin.y - keyboardSize.height);
        [scrollView setContentOffset:point animated:YES];
    }

}
- (void)keyboardWasHidden:(NSNotification *)notif
{
    UIEdgeInsets zeroInsets = UIEdgeInsetsZero;
    UIScrollView *scrollView = (UIScrollView *)self.view;
    [scrollView setContentInset:zeroInsets];
    scrollView.scrollIndicatorInsets = zeroInsets;
}
5
Can you explain how it's not working (how it acts after keyboard hides)? Note that on iOS 7, if you have a translucent navigationBar, your view controller will set a top inset to your scrollViews if not set otherwise. This may be the case here, since you're setting contentInset.top=0, so it may hide some content behind the navigationBar or statusBar. - alex-i
Thanks for your reply. I set the top to the navigationBar.frame.size.height, and it's working now. - yong ho
Write an answer and give alex-i some credit ;) - Nils Ziehn

5 Answers

10
votes

Try this one:

self.automaticallyAdjustsScrollViewInsets = NO;

This is working for me...

1
votes

it might be related to contentSize not working except when set in VCs

- (void)viewDidLayoutSubviews
{
     self.scrollView.contentSize = whatever
}

just saying you might be smashing your head against the wrong wall

0
votes

So, just because I still found this answer useful, here is what I did. I took the advice of @alex-i and the comment by @yong-ho. But for some reason the height of the navigation bar wasn't quite enough.

UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height + 20.0f, 0.0, 0.0, 0.0); 
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;

Like I said, I had to add that 20.0f or my content was still cut off. Not sure why. If I figure it out I'll update my answer.

0
votes

Set contentOffset to zero. It will work in all cases no matter your scroll view is inside navigation controller or any other. Find below the code snippet for same:

- (void)keyboardWasHidden:(NSNotification *)notif
{    
    UIScrollView *scrollView = (UIScrollView *)self.view;
    scrollView.contentOffset = CGPoint.zero
}
0
votes

I also found that if you set a new contentinset exactly the same as the existing inset, the scrollview may ignore it and revert to a zero inset. So an easy workaround is to check that the new contentinset you are setting is at least 1 point different than the last.