Question

This issue has been driving me nuts for the past few hours. So I've got a very simple UIScrollView setup:

-UIScrollView
    -UIImageView

That's it. The scrollview and imageview are generated in Storyboard. Now all I want to do is to have the ability to pinch zoom into this image. Minimum zoom is set to 1 and maximum zoom is 3. The scrollview's delegate is set to my RootViewController

In my RootViewController, I have added this function(Required to support zooming)

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

I believe I've done everything right but whenever I pinch the scrollview, I get the great EXE_BAD_ACCESS. I've tried to look everywhere and I can't seem to find the issue. Crash dump attached below

0   libobjc.A.dylib                 0x34b80f7e objc_msgSend + 22
1   UIKit                           0x3516899e -[UIScrollView _getDelegateZoomView] + 70
2   UIKit                           0x351908f2 -[UIScrollView _zoomScaleFromPresentationLayer:] + 22
3   UIKit                           0x3523bf5a -[UIScrollViewPinchGestureRecognizer touchesBegan:withEvent:] + 102
4   UIKit                           0x35102436 -[UIWindow _sendGesturesForEvent:] + 278
5   UIKit                           0x351021ee -[UIWindow sendEvent:] + 82
6   UIKit                           0x350e868e -[UIApplication sendEvent:] + 350
7   UIKit                           0x350e7f34 _UIApplicationHandleEvent + 5820
8   GraphicsServices                0x32c85224 PurpleEventCallback + 876

What am I doing wrong?

Maybe I'm too sleepy

Was it helpful?

Solution 2

So I solved this the next morning after looking at the code with a fresh pair of eyes. I have a MainViewController initializing and added RootViewController to it's subview. The issue was that this was a _weak reference and ARC was dealloc-ing it.

Assigned it as a global _strong variable on MainViewController and all was fixed.

OTHER TIPS

Had similar issue, solved it by adding the following in the dealloc of the view controller:

self.scrollView.delegate = nil;
self.scrollView = nil;

And I'm using ARC so it seems redundant, but it definitely solves the issue. I suspect that this is the cause of the issue:

@property(nonatomic,assign) id<UIScrollViewDelegate>      delegate;                       // default nil. weak reference

From the UIScrollView.h file

What is _theView? If it's your UIScrollView, then you need to do this:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return [_theView viewForZoomingInScrollView:scrollView];
}

Also, you don't necessarily need this at all. Pinch-zooming should work automatically, unless you explicitly set the scroll view's delegate; if you do this, pinch-zooming should still work automatically in iOS 5, so you would only need to implement viewForZoomingInScrollView: for this to work in iOS 4.

You need to work out the minimum zoom scale for the scroll view. A zoom scale of one means that the content is displayed at normal size. A zoom scale below one shows the content zoomed out, while a zoom scale of greater than one shows the content zoomed in. To get the minimum zoom scale, you calculate how far you’d need to zoom out so that the image fits snugly in your scroll view’s bounds based on its width. Then you do the same based upon the image’s height. The minimum of those two resulting zoom scales will be the scroll view’s minimum zoom scale. That gives you a zoom scale where you can see the entire image when fully zoomed out.

Swift:

let scrollViewFrame = scrollView.frame
let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
let minScale = min(scaleWidth, scaleHeight);
scrollView.minimumZoomScale = minScale;

Objective-C

CGFloat scrollViewFrame = scrollView.frame
CGFloat scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
CGFloat scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
CGFloat minScale = min(scaleWidth, scaleHeight);
scrollView.minimumZoomScale = minScale;

From other projects and personal experience doing heavy GPU on the iOS (endless scroll, maximum bitmap size, etc), I've noticed that each device has it's own threshold. For past projects, I've also hardcoded the below values as the minimumZoomScale to prevent the crashes:

scale :
        {
                iPad : {
                    min : 0.8
                ,   max : 1.6
            }
            , iPhone : {
                    min : 0.25
                ,   max : 1.6
            }
            , iPhone6 : {
                    min : 0.3333
                ,   max : 1.6
            }
            , iPhoneResizable: {
                    min : 1
                ,   max : 1.6
            }
        }

Great tutorial for beginners: http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top