Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
1_TapToZoom/Classes/RootViewController.m
/* |
File: RootViewController.m |
Abstract: View controller to manage a scrollview that displays a zoomable image. |
Version: 1.3 |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple |
Inc. ("Apple") in consideration of your agreement to the following |
terms, and your use, installation, modification or redistribution of |
this Apple software constitutes acceptance of these terms. If you do |
not agree with these terms, please do not use, install, modify or |
redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and |
subject to these terms, Apple grants you a personal, non-exclusive |
license, under Apple's copyrights in this original Apple software (the |
"Apple Software"), to use, reproduce, modify and redistribute the Apple |
Software, with or without modifications, in source and/or binary forms; |
provided that if you redistribute the Apple Software in its entirety and |
without modifications, you must retain this notice and the following |
text and disclaimers in all such redistributions of the Apple Software. |
Neither the name, trademarks, service marks or logos of Apple Inc. may |
be used to endorse or promote products derived from the Apple Software |
without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or |
implied, are granted by Apple herein, including but not limited to any |
patent rights that may be infringed by your derivative works or by other |
works in which the Apple Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGE. |
Copyright (C) 2010 Apple Inc. All Rights Reserved. |
*/ |
#import "RootViewController.h" |
#define ZOOM_VIEW_TAG 100 |
#define ZOOM_STEP 1.5 |
@interface RootViewController (UtilityMethods) |
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center; |
@end |
@implementation RootViewController |
@synthesize imageScrollView, imageView; |
- (void)loadView { |
[super loadView]; |
// set the tag for the image view |
[imageView setTag:ZOOM_VIEW_TAG]; |
// add gesture recognizers to the image view |
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; |
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)]; |
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)]; |
[doubleTap setNumberOfTapsRequired:2]; |
[twoFingerTap setNumberOfTouchesRequired:2]; |
[imageView addGestureRecognizer:singleTap]; |
[imageView addGestureRecognizer:doubleTap]; |
[imageView addGestureRecognizer:twoFingerTap]; |
[singleTap release]; |
[doubleTap release]; |
[twoFingerTap release]; |
// calculate minimum scale to perfectly fit image width, and begin at that scale |
float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width; |
[imageScrollView setMinimumZoomScale:minimumScale]; |
[imageScrollView setZoomScale:minimumScale]; |
} |
- (void)viewDidUnload { |
self.imageScrollView = nil; |
self.imageView = nil; |
} |
- (void)dealloc { |
[imageScrollView release]; |
[imageView release]; |
[super dealloc]; |
} |
#pragma mark UIScrollViewDelegate methods |
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { |
return [imageScrollView viewWithTag:ZOOM_VIEW_TAG]; |
} |
/************************************** NOTE **************************************/ |
/* The following delegate method works around a known bug in zoomToRect:animated: */ |
/* In the next release after 3.0 this workaround will no longer be necessary */ |
/**********************************************************************************/ |
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { |
[scrollView setZoomScale:scale+0.01 animated:NO]; |
[scrollView setZoomScale:scale animated:NO]; |
} |
#pragma mark TapDetectingImageViewDelegate methods |
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer { |
// single tap does nothing for now |
} |
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer { |
// double tap zooms in |
float newScale = [imageScrollView zoomScale] * ZOOM_STEP; |
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; |
[imageScrollView zoomToRect:zoomRect animated:YES]; |
} |
- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer { |
// two-finger tap zooms out |
float newScale = [imageScrollView zoomScale] / ZOOM_STEP; |
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; |
[imageScrollView zoomToRect:zoomRect animated:YES]; |
} |
#pragma mark Utility methods |
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center { |
CGRect zoomRect; |
// the zoom rect is in the content view's coordinates. |
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds. |
// As the zoom scale decreases, so more content is visible, the size of the rect grows. |
zoomRect.size.height = [imageScrollView frame].size.height / scale; |
zoomRect.size.width = [imageScrollView frame].size.width / scale; |
// choose an origin so as to get the right center. |
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0); |
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0); |
return zoomRect; |
} |
@end |
Copyright © 2010 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2010-10-20