Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView scrolls too far after initial zoom

My UIScrollView is populated with a large content and then zoomed with "setZoomScale:animated", such that it fits into the scrollview frame. The view appears properly zoomed out, and properly positioned in the scrollview. However, the user is able to scroll outside the content (the scrollview background color shows). It seems that he can scroll as far as the original content size (as if the content was not zoomed out). Strangely enough, after the user zooms manually the first time, everything works fine, and the scrollview is constrained to the content size again.

I have searched the web, and gone through the Apple docs and examples, but could not find anyone having the same problem. The Apple examples seem to show the same thing as I do.

My content is a custom view that is derived from UIView, and whose CALayer is replaced by a CATiledLayer (as in the Apple examples). The drawing I do myself in drawLayer:inContext:.

Here is a code snippet from MyScrollViewController:

- (void)loadView {
    CGRect frame = [UIScreen mainScreen].applicationFrame;
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:frame];
    scrollView.maximumZoomScale=1.0;
    scrollView.delegate = self;

    ... setup theContentView ...

    scrollView.contentSize = theContentView.bounds.size;
    scrollView.contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
    [scrollView addSubview:theContentView];
    self.view = scrollView;

    double zoomScale = 0.5; // hardcoded for testing
    [scrollView setZoomScale:zoomScale animated:NO];
NSLog(@"zoomscale=%g contentview=%@ contentsize=%@", zoomScale, NSStringFromCGSize(theContentView.bounds.size), NSStringFromCGSize(scrollView.contentSize));

    [scrollView release];
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return theContentView;
}

The NSLog statement shows a correctly set contentSize and zoomscale...

Hoping there is something obvious that I am missing...

like image 472
fishinear Avatar asked Oct 11 '22 02:10

fishinear


1 Answers

I ended up setting the zoomScale on the next runloop (instead of directly from loadView), which worked:

- (void) loadView {
    CGRect frame = [UIScreen mainScreen].applicationFrame;
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:frame];
    scrollView.maximumZoomScale=1.0;
    scrollView.delegate = self;

    ... setup theContentView ...

    scrollView.contentSize = theContentView.bounds.size;
    scrollView.contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
    [scrollView addSubview:theContentView];
    self.view = scrollView;

    // set the zoom level on the next runloop invocation
    [self performSelector:@selector(initialZoom) withObject:nil afterDelay:0];

    [scrollView release];
}

- (void) initialZoom {
    double zoomScale = 0.5; // hardcoded for testing
    UIScrollView *scrollView = (UIScrollView *) self.view;
    [scrollView setZoomScale:zoomScale animated:NO];
}

Another possibility, suggested by Maverick1st, is to set the zoomscale from viewDidAppear, rather than LoadView. That approach has the added advantage that it shows an animation of the zooming, indicating to the user that the view starts in a zoomed state.

- (void) viewDidAppear {
    double zoomScale = 0.5; // hardcoded for testing
    UIScrollView *scrollView = (UIScrollView *) self.view;
    [scrollView setZoomScale:zoomScale animated:YES];
}
like image 159
fishinear Avatar answered Oct 13 '22 01:10

fishinear