Skip to content

Instantly share code, notes, and snippets.

@mikevalstar
Created October 2, 2012 15:35
Show Gist options
  • Save mikevalstar/3820213 to your computer and use it in GitHub Desktop.
Save mikevalstar/3820213 to your computer and use it in GitHub Desktop.
UIImageViewResizable
//
// UIImageViewResizable.h
//
// Created by Mike Valstar on 2012-09-10.
//
#import <UIKit/UIKit.h>
@interface UIImageViewResizable : UIImageView <UIGestureRecognizerDelegate>{
UIPanGestureRecognizer *panGesture;
}
@property(nonatomic) BOOL isZoomable;
- (void) applyGestures;
- (void) scaleToMinimum;
- (void)pinch:(UIPinchGestureRecognizer *)gesture;
- (void)pan:(UIPanGestureRecognizer *)gesture;
- (void)doubleTap:(UITapGestureRecognizer *)gesture;
@end
//
// UIImageViewResizable.m
//
// Created by Mike Valstar on 2012-09-10.
//
#import "UIImageViewResizable.h"
#define MINIMUM_SCALE 1.0
#define MAXIMUM_SCALE 4.0
@implementation UIImageViewResizable
@synthesize isZoomable;
/********************
Public Methods
*******************/
-(void) scaleToMinimum{
CGAffineTransform transform = CGAffineTransformMakeScale(MINIMUM_SCALE, MINIMUM_SCALE);
self.transform = transform;
//check center and move if outside bounds
CGPoint newCenter = CGPointMake(self.frame.origin.x + (self.frame.size.width / 2),
self.frame.origin.y + (self.frame.size.height / 2));
newCenter = [self constrictToBounds:newCenter];
self.frame = CGRectMake(newCenter.x - (self.frame.size.width / 2),
newCenter.y - (self.frame.size.height / 2),
self.frame.size.width,
self.frame.size.height);
[self removeGestureRecognizer:panGesture]; // remove pan gesture when zoomed out
}
-(void) applyGestures{
self.userInteractionEnabled = YES;
// Pinch
UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc]
initWithTarget:self action:@selector(pinch:)];
pgr.delegate = self;
[self addGestureRecognizer:pgr];
// Pan
panGesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(pan:)];
panGesture.delegate = self;
//[self addGestureRecognizer:panGesture]; // Do not add right away wait until zoomed
// Double Tap
UITapGestureRecognizer *dtgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(doubleTap:)];
dtgr.numberOfTapsRequired = 2;
dtgr.delegate = self;
[self addGestureRecognizer:dtgr];
}
/********************
Gestures
*******************/
- (void)pinch:(UIPinchGestureRecognizer *)gesture {
if (isZoomable == NO) return;
if (gesture.state == UIGestureRecognizerStateEnded
|| gesture.state == UIGestureRecognizerStateChanged) {
CGFloat currentScale = self.frame.size.width / self.bounds.size.width;
CGFloat newScale = currentScale * gesture.scale;
[self addGestureRecognizer:panGesture];
if (newScale < MINIMUM_SCALE) {
newScale = MINIMUM_SCALE;
[self removeGestureRecognizer:panGesture]; // remove pan gesture when zoomed out
}
if (newScale > MAXIMUM_SCALE) {
newScale = MAXIMUM_SCALE;
}
CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
self.transform = transform;
gesture.scale = 1;
//check center and move if outside bounds
CGPoint newCenter = CGPointMake(self.frame.origin.x + (self.frame.size.width / 2),
self.frame.origin.y + (self.frame.size.height / 2));
newCenter = [self constrictToBounds:newCenter];
self.frame = CGRectMake(newCenter.x - (self.frame.size.width / 2),
newCenter.y - (self.frame.size.height / 2),
self.frame.size.width,
self.frame.size.height);
}
}
- (void)pan:(UIPanGestureRecognizer *)gesture {
if (isZoomable == NO) return;
CGFloat currentScale = self.frame.size.width / self.bounds.size.width;
CGPoint translation = [gesture translationInView:self];
CGPoint newCenter = CGPointMake(gesture.view.center.x + (translation.x * currentScale),
gesture.view.center.y + (translation.y * currentScale));
newCenter = [self constrictToBounds:newCenter];
gesture.view.center = newCenter;
[gesture setTranslation:CGPointMake(0, 0) inView:self];
}
- (void)doubleTap:(UITapGestureRecognizer *)gesture {
if (isZoomable == NO) return;
CGFloat currentScale = self.frame.size.width / self.bounds.size.width;
if(ceil(currentScale) != ceil(MAXIMUM_SCALE)){
CGAffineTransform transform = CGAffineTransformMakeScale(MAXIMUM_SCALE, MAXIMUM_SCALE);
self.transform = transform;
[self addGestureRecognizer:panGesture];
}else{
CGAffineTransform transform = CGAffineTransformMakeScale(MINIMUM_SCALE, MINIMUM_SCALE);
self.transform = transform;
[self removeGestureRecognizer:panGesture]; // remove pan gesture when zoomed out
}
}
/********************
Internal Methods
*******************/
// Check the bounding box for the resize point
- (CGPoint)constrictToBounds:(CGPoint)point{
CGFloat lowerXBound = ceil(self.bounds.size.width - ( self.frame.size.width / 2 ));
CGFloat higherXBound = floor(lowerXBound + (self.frame.size.width - self.bounds.size.width));
CGFloat lowerYBound = ceil(self.bounds.size.height - ( self.frame.size.height / 2 ));
CGFloat higherYBound = floor(lowerYBound + (self.frame.size.height - self.bounds.size.height));
if ( point.x < lowerXBound)
point.x = lowerXBound;
if ( point.x > higherXBound )
point.x = higherXBound;
if ( point.y < lowerYBound)
point.y = lowerYBound;
if ( point.y > higherYBound )
point.y = higherYBound;
return point;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment