gesture.view on top [UIPanGestureRecognizer] - ios

I have many of views added as subview for UIScrollView where is already a subview for self.view, during dragging the object i can't see object outside of its superview (UIScrollView) and self.view thus I use bringSubviewToFront but it doesn't work
Any hint please?
-(void)handlePan:(UIPanGestureRecognizer *)gesture {
static CGPoint originalCenter;
static CGPoint originalforScroll;
CGPoint newCoord = [gesture locationInView:self.view];
int viewTag = gesture.view.tag;
if(gesture.state == UIGestureRecognizerStateBegan)
{
[gesture.view.superview bringSubviewToFront:gesture.view];
originalCenter = gesture.view.center;
originalforScroll = [gesture locationInView:self.view];
}
if (gesture.state == UIGestureRecognizerStateChanged)
{
CGPoint translate = [gesture translationInView:gesture.view];
gesture.view.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
}
if (gesture.state == UIGestureRecognizerStateEnded ||
gesture.state == UIGestureRecognizerStateFailed ||
gesture.state == UIGestureRecognizerStateCancelled)
{
}
}

Related

Detect UILongPressGestureRecognizer direction not compare initial point

if (gesture.state == UIGestureRecognizerStateBegan) {
_initial = [gesture locationInView:self.view];
}else if (gesture.state == UIGestureRecognizerStateChanged){
CGPoint p = [gesture locationInView:self.view];
double dy = p.y - _initial.y;
if (dy > 0) {
NSLog(#"Finger moved to the up");
}
else {
NSLog(#"Finger moved to the down");
}
}
This is my method to detect UILongPressGestureRecognizer direction, but I want
detect direction not compare initial point but compare stateChanged point.
It's hard to describe, like : form 0 to 7 is up, but 7 to -5 is down and then -5 to -2 is up.
You should use translationInView.
CGPoint translation = [gesture translationInView:view.superview];
if (translation.y>0) {
// moving up
} else {
// moving down
}
A friend of mine give me some advice and it works well:
CGPoint point = [gestureRecognizer locationInView:self.view];
if(gestureRecognizer.state == UIGestureRecognizerStateBegan){
_lastY = point.y;
}else if(gestureRecognizer.state == UIGestureRecognizerStateChanged) {
double y = point.y - _lastY;
if (y < 0.f) {
NSLog(#"****up*****");
}else{
NSLog(#"****down*****");
}
_lastY = point.y;
}
I know it's not a good one but it works, any idea?
Swift 3
Here's a complete function to determine left or right movement of UILongPressGestureRecognizer:
#objc func swipePress (_ sender: UILongPressGestureRecognizer) {
let location = sender.location(in: self.view)
print ("Location : \(location.x)")
if sender.state == .ended {
print("swipe ended")
buttonCreated = false
animateRemoveArrows()
if gestureDirection == "right" {
print("going forward")
if myWebView.canGoForward {
myWebView.goForward() //go forward
} else {
}
} else if gestureDirection == "left" {
print("going backward")
if myWebView.canGoBack {
myWebView.goBack() //go back
} else {
}
} else {
}
} else if sender.state == .began {
gestureDirection = "" // reset direction
print("swipe started")
firstPoisitionX = location.x
firstPoisitionY = location.y
print ("Last x: \(firstPoisitionX)")
} else if sender.state == .changed {
if location.y > (firstPoisitionY + 100) {
print("going up or down")
} else if location.y < (firstPoisitionY - 100) {
print("going up or down")
} else if location.x > (firstPoisitionX + 50) {
print("going right")
if buttonCreated == false { // only create one button
showArrow(direction: "right")
print(rightArrow.center)
gestureDirection = "right"
buttonCreated = true
}
} else if location.x < (firstPoisitionX - 50) {
print("going left")
if buttonCreated == false { // only create one button
showArrow(direction: "left")
print(leftArrow.center)
gestureDirection = "left"
buttonCreated = true
}
}
}
}

UIImageView shakes in UIPinchGestureRecognizer event

I implement pinch operation iOS 8.1 with Swift.
I reference the following links but the image shakes up, down, left and right by little and little.
UIPinchGestureRecognizer. Make zoom in location of fingers, not only center
UIPinchGestureRecognizer position the pinched view between the two fingers
It is my code in UIViewController and sender.view is UIImageView.
func pinchedView(sender:UIPinchGestureRecognizer) {
if sender.numberOfTouches() < 2 {
return
}
if sender.state == UIGestureRecognizerState.Began {
lastScale = 1.0
lastPoint = sender.locationInView(sender.view)
return
}
let scale = 1.0 - (lastScale - sender.scale)
sender.view!.transform = CGAffineTransformScale(sender.view!.transform, scale, scale)
let newPoint = sender.locationInView(sender.view)
var translation = CGPoint()
translation.x = newPoint.x - lastPoint.x
translation.y = newPoint.y - lastPoint.y
sender.view!.transform = CGAffineTransformTranslate(sender.view!.transform, translation.x, translation.y)
lastPoint = sender.locationInView(sender.view)
lastScale = sender.scale
}
Why does UIImageView shake?
Instead of
sender.locationInView(sender.view)
try
sender.locationOfTouch(0, inView: sender.view)
locationInView seems to be picking an undefined touch.

move and rotate an image with fingers on a view ios xcode

Moving and rotating an image with finger's
- (void)viewDidLoad
{
self.imageview.image = [UIImage imageNamed:#"Image.png"];
[self.view addSubview: self.imageview];
[super viewDidLoad];
}
This code is to move image
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
self.imageview.center = touchLocation;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// get touch event
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.PlayVideo];
if ([touch view] == self.view)
{
self.imageview.center = touchLocation;
}
}
This code is to rotate image (T dropped a rotation gesture on to the image and draghed on to .h file)
- (IBAction)regRotation:(UIGestureRecognizer *)sender
{
NSLog(#"rotation");
CGFloat netRotation =0.0;
CGFloat rotation =[(UIRotationGestureRecognizer *)sender rotation];
CGAffineTransform transform=CGAffineTransformMakeRotation(rotation+netRotation);
sender.view.transform=transform;
if(sender.state==UIGestureRecognizerStateEnded)
{
netRotation+=rotation;
}
}
The image is moving and not perfectly rotating
CGFloat firstX;
CGFloat firstY;
CGFloat lastRotation;
- (void)viewDidLoad
{
lastRotation = 0.0;
self.imageview.image = [UIImage imageNamed:#"Image.png"];
[self.view addSubview: self.imageview];
[super viewDidLoad];
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[self.imageview addGestureRecognizer:panRecognizer];
UIRotationGestureRecognizer* rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
}
-(void)move:(id)sender {
[self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
CGFloat finalX = translatedPoint.x + (0*[(UIPanGestureRecognizer*)sender velocityInView:self.imageview].x);
CGFloat finalY = translatedPoint.y + (0*[(UIPanGestureRecognizer*)sender velocityInView:self.imageview].y);
[[sender view] setCenter:CGPointMake(finalX, finalY)];
}
}
-(void)rotate:(id)sender {
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = self.imageview.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[self.imageview setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
}
Its working for me..
Swift 4 answer for Pan, Zoom and Rotate:
var lastRotation : CGFloat = 0.0
var previousScale : CGFloat = 1.0
var beginX : CGFloat = 0.0
var beginY : CGFloat = 0.0
override func viewDidLoad(){
super.viewDidLoad()
let rotationGesture = UIRotationGestureRecognizer.init(target: self, action: #selector(ViewController.rotate(sender:)))
self.imageView.addGestureRecognizer(rotationGesture)
let pinchGesture = UIPinchGestureRecognizer.init(target: self, action: #selector(ViewController.scale(sender:)))
self.imageView.addGestureRecognizer(pinchGesture)
let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(ViewController.pan(sender:)))
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 1
self.imageView.addGestureRecognizer(panGesture)
}
#objc func rotate(sender : Any){
if let sender = sender as? UIRotationGestureRecognizer, let imageView = self.imageView{
if sender.state == .ended{
lastRotation = 0.0
return
}
let rotation : CGFloat = 0.0 - (lastRotation - sender.rotation)
let currentTransform = imageView.transform
let newTransform = currentTransform.rotated(by: rotation)
imageView.transform = newTransform
lastRotation = sender.rotation
}
}
#objc func scale(sender : Any){
if let sender = sender as? UIPinchGestureRecognizer, let imageView = self.imageView{
if sender.state == .ended{
previousScale = 1.0
return
}
let newScale = 1.0 - (previousScale - sender.scale)
let currentTransform = imageView.transform
let newTransform = currentTransform.scaledBy(x: newScale, y: newScale)
imageView.transform = newTransform
previousScale = sender.scale
}
}
#objc func pan(sender : Any){
if let sender = sender as? UIPanGestureRecognizer, let imageView = self.imageView{
var newCenter = sender.translation(in: self.view)
if(sender.state == .began){
beginX = imageView.center.x
beginY = imageView.center.y
}
newCenter = CGPoint.init(x: beginX + newCenter.x, y: beginY + newCenter.y)
imageView.center = newCenter
}
}

Pan, zoom, rotate UIView around anchorPoint using UIGestureRecognizer (iOS)

I'm trying to rotate, pan and zoom an UIView using UIGestureRecognizers. The recognisers are added to the superview, while the rotation,zoom etc is applied to a subview (_baseImage) this is to enable me to overlay other things on top of the subview in future while still receiving the gesture events.
The idea is that the UIView should scale/rotate around an "anchor" point on the subview underneath the two touch points as this seems the most natural. What I'm having problems with is the position of the subview after setting the anchorPoint, and also that the scale and rotation doesn't seem to use the set anchorPoint. My lack of understanding of overlapping co-ordinate systems/CGAffine transforms may be getting me into trouble. Code is pulled from various examples.
Here's my code as it stands at the moment:
-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
CGPoint oldOrigin = view.frame.origin;
view.layer.anchorPoint = anchorPoint;
CGPoint newOrigin = view.frame.origin;
CGPoint transition;
transition.x = newOrigin.x - oldOrigin.x;
transition.y = newOrigin.y - oldOrigin.y;
view.center = CGPointMake (view.center.x - transition.x, view.center.y - transition.y);
}
- (void) updateTransformWithOffset: (CGPoint) translation
{
// Create a blended transform representing translation,
// rotation, and scaling
_baseImage.transform = CGAffineTransformMakeTranslation(translation.x + tx, translation.y + ty);
_baseImage.transform = CGAffineTransformRotate(_baseImage.transform, theta);
_baseImage.transform = CGAffineTransformScale(_baseImage.transform, scale, scale);
}
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)uigr {
if (uigr.state == UIGestureRecognizerStateBegan) {
UIView *piece = self.view;
CGPoint locationInView = [uigr locationInView:_baseImage];
myFrame = _baseImage.frame;
CGPoint newAnchor = CGPointMake( (locationInView.x / piece.bounds.size.width), (locationInView.y / piece.bounds.size.height ));
[self setAnchorPoint:newAnchor forView:_baseImage];
}
}
- (void) handlePinch: (UIPinchGestureRecognizer *) uigr
{
[self adjustAnchorPointForGestureRecognizer:uigr];
if (uigr.state == UIGestureRecognizerStateBegan) {
initScale = scale;
}
scale = initScale*uigr.scale;
[self updateTransformWithOffset:CGPointZero];
}
I've found a solution to my specific problem with the anchorPoint. I was trying to apply transforms to a UIView added in Interface Builder which caused problems with the anchor point and setting new centre point, removing then re-adding the subview seemed to fix it. If anyone has similar problems here is the final code I used on my view controller, it does scale,rotate and pan on a UIView using the touch position as centre for rotate and scale:
#import "ViewController.h"
#interface ViewController (){
CGFloat tx; // x translation
CGFloat ty; // y translation
CGFloat scale; // zoom scale
CGFloat theta; // rotation angle
CGFloat initScale ;
CGFloat initTheta ;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotation:)];
[rotationGesture setDelegate:self];
[self.view addGestureRecognizer:rotationGesture];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handlePinch:)];
[pinchGesture setDelegate:self];
[self.view addGestureRecognizer:pinchGesture];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panGesture setDelegate:self];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[self.view addGestureRecognizer:panGesture];
_baseImage.transform = CGAffineTransformIdentity;
tx = 0.0f; ty = 0.0f; scale = 1.0f; theta = 0.0f;
scale = 1.0;
//removing and adding back to the view seems to fix problems with anchor point I was having, I suspect because of IB layout/scaling and constraints etc
UIView *mySuperView =_baseImage.superview;
[_baseImage removeFromSuperview];
[mySuperView addSubview:_baseImage];
}
-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)myview
{
CGPoint oldOrigin = myview.frame.origin;
myview.layer.anchorPoint = anchorPoint;
CGPoint newOrigin = myview.frame.origin;
CGPoint transition;
transition.x = (newOrigin.x - oldOrigin.x);
transition.y = (newOrigin.y - oldOrigin.y);
CGPoint myNewCenter = CGPointMake (myview.center.x - transition.x, myview.center.y - transition.y);
myview.center = myNewCenter;
}
- (void) updateTransformWithOffset: (CGPoint) translation
{
// Create a blended transform representing translation,
// rotation, and scaling
_baseImage.transform = CGAffineTransformMakeTranslation(translation.x + tx, translation.y + ty);
_baseImage.transform = CGAffineTransformRotate(_baseImage.transform, theta);
_baseImage.transform = CGAffineTransformScale(_baseImage.transform, scale, scale);
}
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)uigr {
if (uigr.state == UIGestureRecognizerStateBegan) {
tx =_baseImage.transform.tx;
ty =_baseImage.transform.ty;
CGPoint locationInView = [uigr locationInView:_baseImage];
CGPoint newAnchor = CGPointMake( (locationInView.x / _baseImage.bounds.size.width), (locationInView.y / _baseImage.bounds.size.height ));
[self setAnchorPoint:newAnchor forView:_baseImage];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// if the gesture recognizers are on different views, don't allow simultaneous recognition
if (gestureRecognizer.view != otherGestureRecognizer.view)
return NO;
if (![gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && ![otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
return YES;
}
return NO;
}
- (void) handleRotation: (UIRotationGestureRecognizer *) uigr
{
if (uigr.state == UIGestureRecognizerStateBegan) {
initTheta = theta;
}
theta = initTheta+uigr.rotation;
[self adjustAnchorPointForGestureRecognizer:uigr];
[self updateTransformWithOffset:CGPointZero];
}
- (void) handlePinch: (UIPinchGestureRecognizer *) uigr
{
if (uigr.state == UIGestureRecognizerStateBegan) {
initScale = scale;
}
scale = initScale*uigr.scale;
[self adjustAnchorPointForGestureRecognizer:uigr];
[self updateTransformWithOffset:CGPointZero];
}
- (void) handlePan: (UIPanGestureRecognizer *) uigr
{
CGPoint translation = [uigr translationInView:_baseImage.superview];
[self adjustAnchorPointForGestureRecognizer:uigr];
[self updateTransformWithOffset:translation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The OP's original solution translated to Swift 2.0. I left out the workaround since it doesn't seem to be an issue anymore.
class ViewController: UIViewController {
var tx:CGFloat = 0.0 // x translation
var ty:CGFloat = 0.0 // y translation
var scale:CGFloat = 1.0 // zoom scale
var theta:CGFloat = 0.0 // rotation angle
var initScale:CGFloat = 1.0
var initTheta:CGFloat = 0.0
var transformedView: UIView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
transformedView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
transformedView.backgroundColor = UIColor.blueColor()
view.addSubview(transformedView)
let rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(OHPlastyViewController.handleRotation(_:)))
rotationGesture.delegate = self
view.addGestureRecognizer(rotationGesture)
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(OHPlastyViewController.handlePinch(_:)))
pinchGesture.delegate = self
view.addGestureRecognizer(pinchGesture)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(OHPlastyViewController.handlePan(_:)))
panGesture.delegate = self
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 1
view.addGestureRecognizer(panGesture)
}
func setAnchorPoint(anchorPoint: CGPoint, forView myView: UIView) {
let oldOrigin: CGPoint = myView.frame.origin
myView.layer.anchorPoint = anchorPoint
let newOrigin = myView.frame.origin
let transition = CGPoint(x: newOrigin.x - oldOrigin.x, y: newOrigin.y - oldOrigin.y)
let myNewCenter = CGPoint(x: myView.center.x - transition.x, y: myView.center.y - transition.y)
myView.center = myNewCenter
}
func updateTransformWithOffset(translation: CGPoint) {
transformedView.transform = CGAffineTransformMakeTranslation(translation.x + tx, translation.y + ty)
transformedView.transform = CGAffineTransformRotate(transformedView.transform, theta)
transformedView.transform = CGAffineTransformScale(transformedView.transform, scale, scale)
}
func adjustAnchorPointForGestureRecognizer(recognizer: UIGestureRecognizer) {
if (recognizer.state == .Began) {
tx = transformedView.transform.tx
ty = transformedView.transform.ty
let locationInView = recognizer.locationInView(transformedView)
let newAnchor = CGPoint(x: (locationInView.x / transformedView.bounds.size.width), y: (locationInView.y / transformedView.bounds.size.height))
setAnchorPoint(newAnchor, forView: transformedView)
}
}
func handleRotation(recognizer: UIRotationGestureRecognizer) {
if recognizer.state == .began {
initTheta = theta
}
theta = initTheta + recognizer.rotation
adjustAnchorPointForGestureRecognizer(recognizer)
updateTransformWithOffset(CGPointZero)
}
func handlePinch(recognizer: UIPinchGestureRecognizer) {
if recognizer.state == .began {
initScale = scale
}
scale = initScale * recognizer.scale
adjustAnchorPointForGestureRecognizer(recognizer)
updateTransformWithOffset(CGPointZero)
}
func handlePan(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translationInView(transformedView.superview)
adjustAnchorPointForGestureRecognizer(recognizer)
updateTransformWithOffset(translation)
}
}
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer.view != otherGestureRecognizer.view {
return false
}
if !gestureRecognizer.isKindOfClass(UITapGestureRecognizer.self) && !otherGestureRecognizer.isKindOfClass(UITapGestureRecognizer.self) {
return true
}
return false
}
}

touchesBegan, touchesEnded, touchesMoved for moving UIView

I need to drag my UIView object. I use this code, but it does not work
float oldX, oldY;
BOOL dragging;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)touch.view;
if (CGRectContainsPoint(label.frame, touchLocation)) {
dragging = YES;
oldX = touchLocation.x;
oldY = touchLocation.y;
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
dragging = NO;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self];
if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)touch.view;
if (dragging) {
CGRect frame = label.frame;
frame.origin.x = label.frame.origin.x + touchLocation.x - oldX;
frame.origin.y = label.frame.origin.y + touchLocation.y - oldY;
label.frame = frame;
}
}
}
I would suggest using a UIPanGestureRecognizer:
-(void)dragging:(UIPanGestureRecognizer *)gesture
{
// Check if this is the first touch
if(gesture.state == UIGestureRecognizerStateBegan)
{
// Store the initial touch so when we change positions we do not snap
self.panCoord = [gesture locationInView:gesture.view];
[self.view bringSubviewToFront:gesture.view];
}
CGPoint newCoord = [gesture locationInView:gesture.view];
// Create the frame offsets to use our finger position in the view.
float dX = newCoord.x-self.panCoord.x;
float dY = newCoord.y-self.panCoord.y;
gesture.view.frame = CGRectMake(gesture.view.frame.origin.x+dX,
gesture.view.frame.origin.y+dY,
gesture.view.frame.size.width,
gesture.view.frame.size.height);
}
This is just a preference of mine. To me it is a lot simpler using a gesture recognizer then using touchesBegan, touchesEnded, touchesMoved. I will use these in cases where the UIPanGestureRecognizer will not work.
This is work code for move UIView objects
float oldX, oldY;
BOOL dragging;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
dragging = YES;
oldX = touchLocation.x;
oldY = touchLocation.y;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
dragging = NO;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)touch.view;
if (dragging) {
CGRect frame = label.frame;
frame.origin.x = label.frame.origin.x + touchLocation.x - oldX;
frame.origin.y = label.frame.origin.y + touchLocation.y - oldY;
label.frame = frame;
}
}
}
There's something a bit strange in your code.
You ask for the location in self, some UIView which presumably contains the UILabel you want to check. This begs the question as to why you do not add the touchesXXX to some UILabel subclass of yours.
This cancels out as you're using the label.frame which is defined in terms of its superview.bounds (your parent UIView you asked the touch location with respect to), but this doesn't make for the most straightforward way to follow what's going on.
With this code i could move my UIView Object anywhere.
My ViewController.swift looks like this.
// code from below
import UIKit
class ViewController: UIViewController {
var location = CGPoint(x: 0, y: 0)
#IBOutlet weak var Person: UIImageView!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
var touch : UITouch! = touches.first! as UITouch
location = touch.location(in: self.view)
Person.center = location
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touch : UITouch! = touches.first! as UITouch
location = touch.location(in: self.view)
Person.center = location
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Person.center = CGPoint(x: 160, y: 330)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//ends
Hope it helps although it is another way to do it than the one mentioned in question.

Resources