Bounds automatically changes on UIScrollView with content insets

Kenny Wyland picture Kenny Wyland · May 6, 2014 · Viewed 9.4k times · Source

I'm using a UIScrollView as my paging scroll view, pagesScrollView. Inside that, I put individual UIScrollViews which are used exclusively for zooming. Inside each of those, I have one view which is the page item which should be zoomable. All of that is inside a UINavigationController with a translucent navbar.

My pagesScrollView has contentInset.top = 64 and bounds.origin.y = -64 (that seems weird to me, but that's what the system is setting automatically for me), and this works just fine. My screen looks great!

However, after I scroll the pagesScrollView even a tiny bit, as soon as scrollViewWillEndDragging is called, the pagesScrollView begins an animated change from bounds.origin.y = -64 to bounds.origin.y = 0 which causes my page items to be obscured by the navbar.

On the left is what it looks like when it loads, on the right is what it looks like after I drag just a few pixels and then let go, it slides up under the navbar (because the bounds.origin.y goes to 0).

enter image description here

The problem is that I don't have any code that is altering the bounds and I don't have any code in the various scroll delegate methods that do anything. I've added a bunch of scroll delegate methods and just added NSLog()s so I can figure out when/where the change is happening, but it's not happening anywhere in my code.

So, I don't know what code I can show you to help you help me.

EDIT: I built a new project from scratch to remove all other variables.. I put a bare UIViewController into a UINavigationController. I put a UIScrollView into my View the entire size of the view. The following code is the entire project.

It turns out the issue (described below) only appears once PAGING IS ENABLED on the UIScrollView! Wtf? :)

Here is a link to download a basic project with only a few lines of code which demonstrates the problem. Just click in the scrollview and you'll see it shift up as the bounds change. http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip

How can I have paging enabled on my scrollview without the bounds freaking out during scrolling and shifting everything under the nav bar?

It's possible to set the navbar to opaque and the problem is avoided, but the ideal is to have standard iOS7 behavior so that after the content view is zoomed, THEN the content is allowed to be under the navbar and should show through the translucency normally.

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    NSArray *colors = @[
                        [UIColor blueColor],
                        [UIColor orangeColor],
                        [UIColor magentaColor],
                        ];

    NSArray *zoomerColors = @[
                        [UIColor greenColor],
                        [UIColor yellowColor],
                        [UIColor purpleColor],
                        ];


    self.scroller.pagingEnabled = YES;

    [self.scroller setContentSize:CGSizeMake(self.scroller.frame.size.width*colors.count, self.scroller.frame.size.height)];

    CGRect subviewFrame = CGRectMake(0, 0, 160, 240);
    for (int index=0; index < colors.count; index++) {
        UIColor *color = [colors objectAtIndex:index];
        UIColor *zoomerColor = [zoomerColors objectAtIndex:index];

        UIView *subview = [[UIView alloc] initWithFrame:subviewFrame];
        subview.backgroundColor = color;

        CGRect zoomerFrame = CGRectMake(index*self.scroller.frame.size.width, 0, self.scroller.frame.size.width, self.scroller.frame.size.height);

        UIScrollView *zoomer = [[UIScrollView alloc] initWithFrame:zoomerFrame];
        [zoomer addSubview:subview];
        zoomer.backgroundColor = zoomerColor;

        [self.scroller addSubview:zoomer];

    }
}

Answer

Misha Vyrko picture Misha Vyrko · May 12, 2014

Just switch off Adjust Scroll View Insets

enter image description here