Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView zoom out issue (IOS 8 GM)

I've been struggling on an issue with my UIScrollView for quite a long time now. Basically, it's a simple zoomable UIScrollView that displays an UIImageView.

When the image is zoomed out at the maximum, we I release my pinch gesture, the animation is weird and does not smoothly zooms in to the minimum zoom scale.

It is actually reproducible in Apple's example at: PhotoScroller Zoom out to the maximum an image and you will see the issue.

I tracked it down to being an extra call to layoutSubviews that is made in iOS 8 (iOS 7 works perfectly).

Has anybody encountered this issue, and if so, found a solution?

like image 215
Champoul Avatar asked Mar 19 '23 11:03

Champoul


2 Answers

The fix from @Jonah solved a similar issue for me, but it is important to not call layoutSubviews directly.

You can achieve a similar and safer effect with the following code:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    [self setNeedsLayout]; // triggers a layout update during the next update cycle
    [self layoutIfNeeded]; // lays out the subviews immediately
}

See Apple's UIView docs for more info: https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/instm/UIView/layoutSubviews

like image 111
dfmuir Avatar answered Mar 29 '23 02:03

dfmuir


I was able to fix it by calling [self. layoutSubviews] in my scrollViewDidZoom method. It's sort of a hack, but it seems to have solved my problem. This may help:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
    [self layoutSubviews];
}

Override layoutSubviews to center content

- (void)layoutSubviews
{
[super layoutSubviews];

// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = super.bounds.size;
CGRect frameToCenter = imageView.frame;

// center horizontally
if (frameToCenter.size.width < boundsSize.width){
    frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
}
else {
    frameToCenter.origin.x = 0;
}
// center vertically
if (frameToCenter.size.height < boundsSize.height){
    frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
}
else {
    frameToCenter.origin.y = 0;
}
imageView.frame = frameToCenter;
}
like image 25
Jonah Avatar answered Mar 29 '23 01:03

Jonah