19

I have a view that has text fields ranging from the top of the screen to the bottom of the screen. Obviously, the bottom text fields get covered up by the keyboard when it pops up, so I set out to get rid of this problem.

I register for notifications in the viewDidLoad method, then when the UIKeyboardDidShowNotification is sent, this method is called:

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    [scrollView scrollRectToVisible:activeField.frame animated:YES];
}

The problem is nothing is getting scrolled at all, let alone scrolled to visible. What am I missing here?

All of my text fields are inside of a scroll view, etc.

Thanks in advance.

Baub
  • 5,004
  • 14
  • 56
  • 99
  • 2
    Set the contentSize, making sure neither width nor height are zero. Then add or subtract from contentInset height until it works. scrollView.contentSize = CGSizeMake(kbSize.width, kbSize.height); scrollView.contentInset = UIEdgeInsetsMake(0, 0, kbSize.height - 250, 0); // (top,left,bottom,right) – Bruce Patin Sep 14 '15 at 19:39

3 Answers3

33

This is a similar post where scrollRectToVisible: is not working correctly, and there is a solution by making sure the contentSize is set correctly. Hope that Helps!

Community
  • 1
  • 1
msgambel
  • 7,320
  • 4
  • 46
  • 62
  • @Yatheesha Because the `UIScrollView` will only scroll with that method if the difference in size between its size and its `contentSize` is sufficient (i.e. if the `contentSize` is 50 points longer than `[[UIScrollView frame] size]`, you'll be able to scroll down 50 points but no more. In this case, we want to scroll more to slide the text above the keyboard, so we have make the `UIScrollView` believe there's more to show, which we do by increasing the `contentSize`. – dadude999 Dec 08 '14 at 06:05
  • 1
    While answer is redirected to other link, helped me to solve that I forgot to add bottom to subview added inside scrollview, contentSize width was perfect but height was 0! Thanks :) – Kiran Jasvanee Mar 27 '17 at 13:17
  • 4
    ..always `contentSize`, isn't it ;-) – Jay Mar 29 '17 at 09:24
  • 3
    @Jay here the same... I was SO sure that `contentSize` is perfect - but no, it wasn't... (width in my case) – swalkner Aug 22 '18 at 14:37
2

Sending a message to myself in the future: Your contentSize width is 0.

When the width of contentSize is 0, scrollRectToVisible has no effect.

Also, your contentSize width is 0 because of AutoLayout.

See https://developer.apple.com/library/archive/technotes/tn2154/_index.html

Also, it's because you're not explicitly setting the width of the content view, but are doing something silly like centering the content view within the scroll view, and maybe it's the case that UIScrollView isn't clever enough to figure out how to set contentSize in the context of Auto Layout in this situation.

Drew
  • 926
  • 1
  • 9
  • 13
0

I had a UIScrollView that would scroll in both dimensions, and it had a single subview. The contentSize of the scroll view didn't match the bounds size of the subview, so scrollRectToVisible (with the provided CGRect in the subview's coordinate space) didn't scroll to the right place. Converting the coordinate space made it work as intended:

let targetPoint = CGPoint(x: 200, y: 200)
let scrollTarget = contentView.convert(targetPoint, to: scrollView)
let targetRect = CGRect(center: scrollTarget, size: .init(width: 150, height: 150))
scrollView.scrollRectToVisible(targetRect, animated: false)
SlimeBaron
  • 645
  • 8
  • 17