Skip to content

Instantly share code, notes, and snippets.

@mikebob
Created October 24, 2011 11:27
Show Gist options
  • Save mikebob/1308814 to your computer and use it in GitHub Desktop.
Save mikebob/1308814 to your computer and use it in GitHub Desktop.
Custom UIScrollView that supports pinch and double tap zooming
//
// SPXFrameScroller.h
// SmartyPix
//
// Created by Mike Bobiney on 8/23/11.
// Copyright 2011 Tap Through Apps LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#define kHideNavigationBar @"SPXHideNavigationBar"
#define kShowNavigationBar @"SPXShowNavigationBar"
@interface SPXFrameScroller : UIScrollView<UIScrollViewDelegate>
{
BOOL isZoomed;
BOOL isStatusBarVisible;
@private
UIImageView *imageToBeFramed;
}
@property (readonly, nonatomic, retain) UIImageView *imageToBeFramed;
-(id)initWithFrame:(CGRect)frame;
- (CGRect)zoomRectForScrollView:(UIScrollView *)scrollView withScale:(float)scale withCenter:(CGPoint)center;
@end
//
// SPXFrameScroller.m
// SmartyPix
//
// Created by Mike Bobiney on 8/23/11.
// Copyright 2011 Tap Through Apps LLC. All rights reserved.
//
#import "SPXFrameScroller.h"
@implementation SPXFrameScroller
@synthesize imageToBeFramed;
-(UIImageView *)imageToBeFramed
{
return [self.subviews objectAtIndex:0];
}
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self) {
self.minimumZoomScale = 0.25;
self.maximumZoomScale = 1.00;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.autoresizesSubviews = YES;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
self.delegate = self;
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = self.imageToBeFramed.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;
self.imageToBeFramed.frame = frameToCenter;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
// return the first subview of the scroll view
return self.imageToBeFramed;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([touch tapCount] == 1)
{
if (isStatusBarVisible) {
[[NSNotificationCenter defaultCenter] postNotificationName:kHideNavigationBar object:nil];
isStatusBarVisible = NO;
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:kShowNavigationBar object:nil];
isStatusBarVisible = YES;
}
}
else if ([touch tapCount] == 2)
{
if(!isZoomed){
CGRect rect = [self.imageToBeFramed bounds];
[self zoomToRect:rect animated:YES];
isZoomed = YES;
}else {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.imageToBeFramed];
CGRect zrect = [self zoomRectForScrollView:self withScale:0.6 withCenter:touchPoint];
[self zoomToRect:zrect animated:YES];
isZoomed = NO;
}
}
}
- (CGRect)zoomRectForScrollView:(UIScrollView *)scrollView withScale:(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 = scrollView.frame.size.height / scale;
zoomRect.size.width = scrollView.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;
}
-(void)dealloc
{
[imageToBeFramed release];
[super dealloc];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment