Drag a Cgrect Using Uipangesturerecognizer

Drag a CGRect using UIPanGestureRecognizer

Try like this (check comments through code):

@IBDesignable
class Rectangle: UIView {

@IBInspectable var color: UIColor = .clear {
didSet { backgroundColor = color }
}
// draw your view using the background color
override func draw(_ rect: CGRect) {
backgroundColor?.set()
UIBezierPath(rect: rect).fill()
}
// add the gesture recognizer to your view
override func didMoveToSuperview() {
addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan)))
}
// your gesture selector
@objc func pan(_ gesture: UIPanGestureRecognizer) {
// update your view frame origin
frame.origin += gesture.translation(in: self)
// reset the gesture translation
gesture.setTranslation(.zero, in: self)
}
}

extension CGPoint {
static func +=(lhs: inout CGPoint, rhs: CGPoint) {
lhs.x += rhs.x
lhs.y += rhs.y
}
}

To draw rectangles on your view when panning you can do as follow:

import UIKit

class ViewController: UIViewController {
var rectangles: [Rectangle] = []
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan)))
}
@objc func pan(_ gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
let rectangle = Rectangle(frame: .init(origin: gesture.location(in: view), size: .init(width: 0, height: 0)))
rectangle.fillColor = .red
rectangle.strokeColor = .white
rectangle.lineWidth = 3
view.addSubview(rectangle)
rectangles.append(rectangle)
case .changed:
let distance = gesture.translation(in: view)
let index = rectangles.index(before: rectangles.endIndex)
let frame = rectangles[index].frame
rectangles[index].frame = .init(origin: frame.origin, size: .init(width: frame.width + distance.x, height: frame.height + distance.y))
rectangles[index].setNeedsDisplay()
gesture.setTranslation(.zero, in: view)
case .ended:
break
default:
break
}
}
}

Sample Project

Get UIView from CGRect using UIPanGestureRecognizer - Swift 2.0

Use this modified code :

class ViewController: UIViewController {

@IBOutlet var panView: UIView!

override func viewDidLoad() {
super.viewDidLoad()

}

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)

panView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "panViewGesture:"))
}

func panViewGesture(sender: UIPanGestureRecognizer) {

let locationInView = sender.locationInView(self.view)

if sender.state == .Changed {

panView.center = locationInView

if let view = intersectingViewWithView(panView) {
view.backgroundColor = panView.backgroundColor
}
}

}

func intersectingViewWithView(panView: UIView) -> UIView? {
for view in self.view.subviews {
if view != panView {
if CGRectIntersectsRect(panView.frame, view.frame) {
return view
}
}
}
return nil
}
}

How to set boundaries of dragging control using UIPanGestureRecognizer?

The code is not most intuitive but assuming everything else works the problem is that it only goes off the bounds on right and bottom. Look at your condition with:

(view.frame.origin.x + translation.x <= view.frame.width)
(view.frame.origin.y + translation.y <= view.frame.height)

So it says that the origin may not be greater than size of bounds what you want to do is check the maximum values of the inner view:

(view.frame.maxX + translation.x <= view.frame.width)
(view.frame.maxY + translation.y <= view.frame.height)

But this procedure in general may produce issues. Imagine that user swipes very quickly rightwards. And that the maximum center.x could be 100. Current center.x is 50 and user drags it in a single frame to 200. Your condition will fail and your label will stay at 50 instead of 100. I would go with clamping the frame to bounds.

Something like the following should do:

func clampFrame(_ frame: CGRect, inBounds bounds: CGRect) -> CGRect {
let center: CGPoint = CGPoint(x: max(bounds.minX + frame.width*0.5, min(frame.midX, bounds.maxX - frame.width*0.5)),
y: max(bounds.minY + frame.height*0.5, min(frame.midY, bounds.maxY - frame.height*0.5)))
return CGRect(x: center.x-frame.width*0.5, y: center.y-frame.height*0.5, width: frame.width, height: frame.height)
}

func moveFrame(_ frame: CGRect, by translation: CGPoint, constrainedTo bounds: CGRect) -> CGRect {
var newFrame = frame
newFrame.origin.x += translation.x
newFrame.origin.y += translation.y
return clampFrame(newFrame, inBounds: bounds)
}

There may be other issues as well using "translation" procedure. I would go with finding a location in view. Please see the following working example:

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let myView = MyView(frame: CGRect(x: 100.0, y: 100.0, width: 200.0, height: 200.0))
myView.backgroundColor = UIColor.green
view.addSubview(myView)
let label = UILabel(frame: .zero)
label.backgroundColor = UIColor.blue.withAlphaComponent(0.2)
label.font = UIFont.systemFont(ofSize: 50.0)
label.text = "Hi!"
label.sizeToFit()
myView.addSubview(label)
label.addGestureRecognizer(UIPanGestureRecognizer(target: myView, action: #selector(MyView.handlePan)))
label.isUserInteractionEnabled = true
}

}

class MyView: UIView {

func clampFrame(_ frame: CGRect, inBounds bounds: CGRect) -> CGRect {
let center: CGPoint = CGPoint(x: max(bounds.minX + frame.width*0.5, min(frame.midX, bounds.maxX - frame.width*0.5)),
y: max(bounds.minY + frame.height*0.5, min(frame.midY, bounds.maxY - frame.height*0.5)))
return CGRect(x: center.x-frame.width*0.5, y: center.y-frame.height*0.5, width: frame.width, height: frame.height)
}

func moveFrame(_ frame: CGRect, by translation: CGPoint, constrainedTo bounds: CGRect) -> CGRect {
var newFrame = frame
newFrame.origin.x += translation.x
newFrame.origin.y += translation.y
return clampFrame(newFrame, inBounds: bounds)
}

private var startLocation: CGPoint = .zero
private var startFrame: CGRect = .zero

@objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
guard let label = gestureRecognizer.view else { return }

if gestureRecognizer.state == .began {
startLocation = gestureRecognizer.location(in: self)
startFrame = label.frame
} else if gestureRecognizer.state == .changed {
let newLocation = gestureRecognizer.location(in: self)
let translation = CGPoint(x: newLocation.x-startLocation.x, y: newLocation.y-startLocation.y)

label.frame = moveFrame(startFrame, by: translation, constrainedTo: self.bounds)
}

}

}

Moving UIView within Parent UIView (UIPanGestureRecognizer)

First get the new frame of your UIImageView and check if it is completely inside its superView using CGRectContainsRect() method. If yes, then set UImageView's frame to new frame.

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {

CGPoint translation = [recognizer translationInView:self.view];
CGRect recognizerFrame = recognizer.view.frame;
recognizerFrame.origin.x += translation.x;
recognizerFrame.origin.y += translation.y;

// Check if UIImageView is completely inside its superView
if (CGRectContainsRect(self.view.bounds, recognizerFrame)) {
recognizer.view.frame = recognizerFrame;
}
// Else check if UIImageView is vertically and/or horizontally outside of its
// superView. If yes, then set UImageView's frame accordingly.
// This is required so that when user pans rapidly then it provides smooth translation.
else {
// Check vertically
if (recognizerFrame.origin.y < self.view.bounds.origin.y) {
recognizerFrame.origin.y = 0;
}
else if (recognizerFrame.origin.y + recognizerFrame.size.height > self.view.bounds.size.height) {
recognizerFrame.origin.y = self.view.bounds.size.height - recognizerFrame.size.height;
}

// Check horizantally
if (recognizerFrame.origin.x < self.view.bounds.origin.x) {
recognizerFrame.origin.x = 0;
}
else if (recognizerFrame.origin.x + recognizerFrame.size.width > self.view.bounds.size.width) {
recognizerFrame.origin.x = self.view.bounds.size.width - recognizerFrame.size.width;
}
}

// Reset translation so that on next pan recognition
// we get correct translation value
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}

Make sure that you pass bounds of superView and frame of UIImageView so that both CGRects are in same coordinate system.

How to use UIPanGestureRecognizer to move object? iPhone/iPad

I found the tutorial Working with UIGestureRecognizers, and I think that is what I am looking for. It helped me come up with the following solution:

-(IBAction) someMethod {
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[ViewMain addGestureRecognizer:panRecognizer];
[panRecognizer release];
}

-(void)move:(UIPanGestureRecognizer*)sender {
[self.view bringSubviewToFront:sender.view];
CGPoint translatedPoint = [sender translationInView:sender.view.superview];

if (sender.state == UIGestureRecognizerStateBegan) {
firstX = sender.view.center.x;
firstY = sender.view.center.y;
}

translatedPoint = CGPointMake(sender.view.center.x+translatedPoint.x, sender.view.center.y+translatedPoint.y);

[sender.view setCenter:translatedPoint];
[sender setTranslation:CGPointZero inView:sender.view];

if (sender.state == UIGestureRecognizerStateEnded) {
CGFloat velocityX = (0.2*[sender velocityInView:self.view].x);
CGFloat velocityY = (0.2*[sender velocityInView:self.view].y);

CGFloat finalX = translatedPoint.x + velocityX;
CGFloat finalY = translatedPoint.y + velocityY;// translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);

if (finalX < 0) {
finalX = 0;
} else if (finalX > self.view.frame.size.width) {
finalX = self.view.frame.size.width;
}

if (finalY < 50) { // to avoid status bar
finalY = 50;
} else if (finalY > self.view.frame.size.height) {
finalY = self.view.frame.size.height;
}

CGFloat animationDuration = (ABS(velocityX)*.0002)+.2;

NSLog(@"the duration is: %f", animationDuration);

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidFinish)];
[[sender view] setCenter:CGPointMake(finalX, finalY)];
[UIView commitAnimations];
}
}

Draggable UIView Swift 3

Step 1 : Take one View which you want to drag in storyBoard.

@IBOutlet weak var viewDrag: UIView!

Step 2 : Add PanGesture.

var panGesture       = UIPanGestureRecognizer()

Step 3 : In ViewDidLoad adding the below code.

override func viewDidLoad() {
super.viewDidLoad()

panGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.draggedView(_:)))
viewDrag.isUserInteractionEnabled = true
viewDrag.addGestureRecognizer(panGesture)

}

Step 4 : Code for draggedView.

func draggedView(_ sender:UIPanGestureRecognizer){
self.view.bringSubview(toFront: viewDrag)
let translation = sender.translation(in: self.view)
viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x, y: viewDrag.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: self.view)
}

Step 5 : Output.

GIF

iOS, can UIPanGesture be used to do UIImageView corner drag for resizing?

After some research I figured out how to modify the transform for a corner/side dragging pan, to resize an image. Here are the key elements to make it work:

  • Save the CGAffineTransform in each gesture (pan, pinch, rotate) if
    the recognizer state = UIGestureRecognizerStateBegan
  • Apply new CGAAffineTransforms on the saved initial transform in each gesture (pan, pinch, rotate)
  • Save the corner/side detected in the UIGestureRecognizerStateBegan state
  • Clear the corner/side detected in the UIGestureRecognizerStateEnded state
  • For pan gesture, adjust the translation x/y values based on corner/side detected
  • Make sure touch radius is large enough to be useful (24 was too small, 48 works well)

The transform worked like this:

// pan the image
recognizer.view.transform = CGAffineTransformTranslate(initialTransform, tx, ty);

if (scaleIt) {
// the origin or size changed
recognizer.view.frame = newFrame;
}

The tx and ty values were the defaults returned from the recognizer if the pan was from the center of the image. But if the user touch was near a corner or side of the view frame, the tx/ty and the frame origin are adjusted to resize the view making it appear as if that corner or side were being dragged to resize the view.

For example:

CGRect newFrame = recognizer.view.frame;

if (currentDragType == DRAG_TOPLEFT) {
tx = -translation.x;
ty = -translation.y;
newFrame.origin.x += translation.x;
newFrame.origin.y += translation.y;
newFrame.size.width -= translation.x;
newFrame.size.height -= translation.y;
} else if (currentDragType == DRAG_TOPRIGHT) {
tx = translation.x;
ty = -translation.y;
newFrame.origin.y += translation.y;
newFrame.size.width += translation.x;
newFrame.size.height -= translation.y;
}

This makes the top left corner or top right corner move in or out according to how far the touch moved. Unlike a center pan, where the whole view moves along with the touch, the opposite corner (or side) remains fixed.

There were 2 problems I did not resolve:

  • if the image is rotated significantly, the corner/side detection (pan) does not work because I did not check for the touch in the rotated coordinate system (but the center pan still works fine)
  • once the image is rotated, pinch gestures work erratically and can resize an image to zero, making it invisible

I created a simple demo and uploaded it to GitHub: https://github.com/ByteSlinger/ImageGestureDemo

Yes, I know that link could go away someday, so here's the code:

ViewController.h

//
// ViewController.h
// ImageGestureDemo
//
// Created by ByteSlinger on 6/21/18.
// Copyright © 2018 ByteSlinger. All rights reserved.
//

#import <UIKit/UIKit.h>
NSString *APP_TITLE = @"Image Gesture Demo";
NSString *INTRO_ALERT = @"\nDrag, Pinch and Rotate the Image!"
"\n\nYou can also Drag, Pinch and Rotate the background image."
"\n\nDouble tap an image to reset it";

float touchRadius = 48; // max distance from corners to touch point

typedef NS_ENUM(NSInteger, DragType) {
DRAG_OFF,
DRAG_ON,
DRAG_CENTER,
DRAG_TOP,
DRAG_BOTTOM,
DRAG_LEFT,
DRAG_RIGHT,
DRAG_TOPLEFT,
DRAG_TOPRIGHT,
DRAG_BOTTOMLEFT,
DRAG_BOTTOMRIGHT
};

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>

//callback to process gesture events
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer;
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer;
- (IBAction)handleRotate:(UIRotationGestureRecognizer *)recognizer;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
@end

ViewController.m

//
// ViewController.m
// ImageGestureDemo
//
// This is a DEMO. It shows how to pan, pinch, rotate and drag/resize a UIImageView.
//
// There is a background image and a foreground image. Both images can be
// panned, pinched and rotated, but only the foreground image can be resized
// by dragging one of it's corners or it's sides.
//
// NOTE: Sure, much of this code could have been put into a subclass of UIView
// or UIImageView. But for simplicity and reference sake, all code and
// methods are in one place, this ViewController subclass. There is no
// error checking at all. App tested on an iPhone 6+ and an iPad gen3.
//
// Features:
// - allows an image to be resized with pan gesture by dragging corners and sides
// - background image can be modified (pan, pinch, rotate)
// - foreground image can be modified (pan, pinch, rotate, drag/resize)
// - all image manipulation done within gestures linked from storyboard
// - all finger touches on screen show with yellow circles
// - when dragging, the touch circles turn to red (so you know when gestures start)
// - double tap on foreground image resets it to original size and rotation
// - double tap on background resets it and also resets the foreground image
// - screen and image touch and size info displayed on screen
// - uses CGAffineTransform objects for image manipulation
// - uses UIGestureRecognizerStateBegan in gestures to save transforms (the secret sauce...)
//
// Known Issues:
// - when the image is rotated, determining if a touch is on a corner or side
// does not work for large rotations. Need to check touch points against
// non rotated view frame and adjust accordingly.
// - after rotations, pinch and resize can shrink image to invisibility despite
// code attempts to prevent it.
//
// Created by ByteSlinger on 6/21/18.
// Copyright © 2018 ByteSlinger. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIImageView *backgroundImageView;
@property (strong, nonatomic) IBOutlet UIImageView *foregroundImageView;
@property (strong, nonatomic) IBOutlet UILabel *screenInfoLabel;
@property (strong, nonatomic) IBOutlet UILabel *touchInfoLabel;
@property (strong, nonatomic) IBOutlet UILabel *imageInfoLabel;
@property (strong, nonatomic) IBOutlet UILabel *backgroundInfoLabel;
@property (strong, nonatomic) IBOutlet UILabel *changeInfoLabel;
@property (strong, nonatomic) IBOutlet UITapGestureRecognizer *backgroundTapGesture;
@property (strong, nonatomic) IBOutlet UITapGestureRecognizer *foregroundTapGesture;
@end

@implementation ViewController
CGRect originalImageFrame;
CGRect originalBackgroundFrame;
CGAffineTransform originalImageTransform;
CGAffineTransform originalBackgroundTransform;
NSMutableArray* touchCircles = nil;
DragType currentDragType = DRAG_OFF;

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

// set this to whatever your desired touch radius is
touchRadius = 48;

// In Storyboard this must have set to 1, then this seems to work ok
// when setting the double tap here
_foregroundTapGesture.numberOfTapsRequired = 2;
_backgroundTapGesture.numberOfTapsRequired = 2;

[self centerImageView:_foregroundImageView];

originalImageFrame = _foregroundImageView.frame;
originalBackgroundFrame = _backgroundImageView.frame;
originalImageTransform = _foregroundImageView.transform;
originalBackgroundTransform = _backgroundImageView.transform;

_backgroundImageView.contentMode = UIViewContentModeCenter;
_foregroundImageView.contentMode = UIViewContentModeScaleToFill; // allow stretch
[_backgroundImageView setUserInteractionEnabled:YES];
[_backgroundImageView setMultipleTouchEnabled:YES];
[_foregroundImageView setUserInteractionEnabled:YES];
[_foregroundImageView setMultipleTouchEnabled:YES];

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];

[_touchInfoLabel setText:nil];
[_changeInfoLabel setText:nil];
[_imageInfoLabel setText:nil];
[_backgroundInfoLabel setText:nil];

touchCircles = [[NSMutableArray alloc] init];
}

- (void)viewDidAppear:(BOOL)animated {
[self alert:APP_TITLE :INTRO_ALERT];
}

- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
/* start special animation */
break;

case UIDeviceOrientationPortraitUpsideDown:
/* start special animation */
break;

default:
break;
};

[_screenInfoLabel setText:[NSString stringWithFormat:@"Screen: %.0f/%.0f",
self.view.frame.size.width,self.view.frame.size.height]];
}

//
// Update the info labels from the passed objects
//
- (void) updateInfo:(UIView *)imageView touch:(CGPoint)touch change:(CGPoint)change {
NSString *label;
UILabel *infoLabel;

if (imageView == _foregroundImageView) {
label = @"Image: %0.f/%0.f, %0.f/%0.f";
infoLabel = _imageInfoLabel;
} else {
label = @"Background: %0.f/%0.f, %0.f/%0.f";
infoLabel = _backgroundInfoLabel;
}

[infoLabel setText:[NSString stringWithFormat:label,
imageView.layer.frame.origin.x,
imageView.layer.frame.origin.y,
imageView.layer.frame.size.width,
imageView.layer.frame.size.height]];

[_touchInfoLabel setText:[NSString stringWithFormat:@"Touch: %0.f/%.0f",
touch.x,touch.y]];

[_changeInfoLabel setText:[NSString stringWithFormat:@"Change: %0.f/%.0f",
change.x,change.y]];
}

//
// Center the passed image frame within it's bounds
//
- (void)centerImageView:(UIImageView *)imageView {
CGSize boundsSize = self.view.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;
}

//
// Remove all touch circles
//
- (void)removeTouchCircles {
[touchCircles makeObjectsPerformSelector: @selector(removeFromSuperview)];
[touchCircles removeAllObjects];
}

//
// Draw a circle around the passed point where the user has touched the screen
//
- (void)drawTouchCircle:(UIView *)view fromCenter:(CGPoint)point ofRadius:(float)radius {
CGRect frame = CGRectMake(point.x - view.frame.origin.x - radius,
point.y - view.frame.origin.y - radius,
radius * 2, radius * 2);

UIView *circle = [[UIView alloc] initWithFrame:frame];
circle.alpha = 0.5;
circle.layer.cornerRadius = radius;
circle.backgroundColor = currentDragType == DRAG_OFF ? [UIColor yellowColor] : [UIColor redColor];
[circle.layer setBorderWidth:1.0];
[circle.layer setBorderColor:[[UIColor blackColor]CGColor]];

[view addSubview:circle];

[touchCircles addObject:circle];
}

//
// Draw a touch circle for the passed user touch
//
- (void)handleTouchEvent:(UIView *) view
atPoint:(CGPoint) point
forState:(UIGestureRecognizerState) state
clear:(Boolean) clear {
//NSLog(@"handleTouchEvent");
if (clear) {
[self removeTouchCircles];
}

if (state == UIGestureRecognizerStateEnded) {
[self removeTouchCircles];
} else {
[self drawTouchCircle:self.view fromCenter:point ofRadius:touchRadius];
}

[_touchInfoLabel setText:[NSString stringWithFormat:@"Touch: %0.f/%.0f",
point.x,point.y]];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//NSLog(@"touchesBegan");
[self removeTouchCircles];

NSSet *allTouches = [event allTouches];
NSArray *allObjects = [allTouches allObjects];
for (int i = 0;i < [allObjects count];i++)
{
UITouch *touch = [allObjects objectAtIndex:i];
CGPoint location = [touch locationInView: self.view];
[self handleTouchEvent:touch.view atPoint:location forState:UIGestureRecognizerStateBegan clear:NO];
}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
//NSLog(@"touchesMoved");
[self removeTouchCircles];

NSSet *allTouches = [event allTouches];
NSArray *allObjects = [allTouches allObjects];
for (int i = 0;i < [allObjects count];i++)
{
UITouch *touch = [allObjects objectAtIndex:i];
CGPoint location = [touch locationInView: self.view];
[self handleTouchEvent:touch.view atPoint:location forState:UIGestureRecognizerStateChanged clear:NO];
}
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//NSLog(@"touchesEnded");
[self removeTouchCircles];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//NSLog(@"touchesCancelled");
[self removeTouchCircles];
}

//
// Double tap resets passed image. If background image, also reset foreground image.
//
- (IBAction)handleDoubleTap:(UITapGestureRecognizer *)recognizer {
CGPoint touch = [recognizer locationInView: self.view];

if (recognizer.state == UIGestureRecognizerStateBegan ||
recognizer.state == UIGestureRecognizerStateChanged) {
[self handleTouchEvent:recognizer.view atPoint:touch forState:recognizer.state clear:NO];
} else {
[self removeTouchCircles];
}
[self alert:@"Reset" :@"The Image has been Reset!"];

CGRect frame = originalImageFrame;
CGAffineTransform transform = originalImageTransform;

if (recognizer.view == _backgroundImageView) {
_foregroundImageView.transform = transform;
_foregroundImageView.frame = frame;
[self updateInfo:_foregroundImageView touch:touch change:CGPointZero];

frame = originalBackgroundFrame;
transform = originalBackgroundTransform;
}

recognizer.view.transform = transform;
recognizer.view.frame = frame;
[self updateInfo:recognizer.view touch:touch change:CGPointZero];
}

- (void) setDragType:(CGRect)frame withTouch:(CGPoint)touch {
// the corners and sides of the current view frame
CGRect topLeft = CGRectMake(frame.origin.x,frame.origin.y,
touchRadius, touchRadius);
CGRect bottomLeft = CGRectMake(frame.origin.x,
frame.origin.y + frame.size.height - touchRadius,
touchRadius, touchRadius);
CGRect topRight = CGRectMake(frame.origin.x + frame.size.width - touchRadius,
frame.origin.y,
touchRadius, touchRadius);
CGRect bottomRight = CGRectMake(frame.origin.x + frame.size.width - touchRadius,
frame.origin.y + frame.size.height - touchRadius,
touchRadius, touchRadius);
CGRect leftSide = CGRectMake(frame.origin.x,frame.origin.y,
touchRadius, frame.size.height);
CGRect rightSide = CGRectMake(frame.origin.x + frame.size.width - touchRadius,
frame.origin.y,
touchRadius, frame.size.height);
CGRect topSide = CGRectMake(frame.origin.x,frame.origin.y,
frame.size.width, touchRadius);
CGRect bottomSide = CGRectMake(frame.origin.x,
frame.origin.y + frame.size.height - touchRadius,
frame.size.width, touchRadius);

if (CGRectContainsPoint(topLeft, touch)) {
currentDragType = DRAG_TOPLEFT;
} else if (CGRectContainsPoint(topRight, touch)) {
currentDragType = DRAG_TOPRIGHT;
} else if (CGRectContainsPoint(bottomLeft, touch)) {
currentDragType = DRAG_BOTTOMLEFT;
} else if (CGRectContainsPoint(bottomRight, touch)) {
currentDragType = DRAG_BOTTOMRIGHT;
} else if (CGRectContainsPoint(topSide, touch))


Related Topics



Leave a reply



Submit