5
votes

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...

2
Had anyone a solution for this? i have the same problem, just the other way round. My Scrollview is to small to display the contained image (i cannot scroll to the bottom of the image) But after zooming once everything is fine.Maverick1st
I ended up setting the zoomScale on the next runloop (instead of directly from loadView), which worked: "[self performSelector:@selector(initialZoom) withObject:nil afterDelay:0];". But I rewrote a lot of other stuff as well, so I am not sure whether that is the only thing needed.fishinear
I had the same idea finally and it works perfectly. One bonus you get, when setting the zoomscale in viewDidAppear is, that the user sees an animated zoom and thus knows, the image he views is zoomable :)Maverick1st
btw. Would you mind writing this as answer and tick it for the right answer, so other users se it on first glance, that the question is answered?Maverick1st
@Maverick1st Done. Did you set the zoomscale directly from viewDidAppear, or through a performSelector? Then I can add that to the answer as well.fishinear

2 Answers

3
votes

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];
}
1
votes

I'm new at this but you could try clipping subviews. I created a scroll view with interface builder, and there in the attributes inspector was a checkbox clip subviews, so i think you should do something like that, only programmatically. Hope that helps.