How to limit a roaming view using pan gestures

I have a UIImageView that moves using pan gestures.

 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; [self.photoMask addGestureRecognizer:pan]; 

I would like to limit the area that can be moved to the screen. Instead of letting the user drag the view directly toward the screen, I want to limit it to a specific edge. How can i do this?

Also, how is this handled when turning?

EDIT ---

 #pragma mark - Gesture Recognizer -(void)handlePan:(UIPanGestureRecognizer *)gesture { NSLog(@"Pan Gesture"); gesture.view.center = [gesture locationInView:self.view]; } 

This is my current pan handling method. What I need to do is to continue moving the image along the center point, and also limit its movement if it is close to the edge of the screen, for example, by 50.

+6
source share
4 answers

One possible solution to this is in your handlePan method, check the location of the point on the screen and commit this change only if you want to limit it.

For instance,

 -(void) handlePan:(UIGestureRecognizer*)panGes{ CGPoint point = [panGes locationInView:self.view]; //Only allow movement up to within 100 pixels of the right bound of the screen if (point.x < [UIScreen mainScreen].bounds.size.width - 100) { CGRect newframe = CGRectMake(point.x, point.y, theImageView.frame.size.width, theImageView.frame.size.height); theImageView.frame = newframe; } } 

I believe that this would also correctly handle any screen rotation

EDIT

To move the image in the center of its frame, the handlePan method might look something like this.

 -(void)handlePan:(UIPanGestureRecognizer *)gesture { CGPoint point = [gesture locationInView:self.view]; //Only allow movement up to within 50 pixels of the bounds of the screen //Ex. (IPhone 5) CGRect boundsRect = CGRectMake(50, 50, 220, 448); if (CGRectContainsPoint(boundsRect, point)) { imgView.center = point; } } 

Check if the point is within your desired boundaries, and if so, set the center of the image frame to that point.

+7
source

I'm not sure I'm too simplistic, but I think you can do this using the if clause.

 -(void)handlePan:(UIPanGestureRecognizer*)gesture { UIImageView *viewToDrag = gesture.view; // this is the view you want to move CGPoint translation = [gesture translationInView:viewToDrag.superview]; // get the movement delta CGRect movedFrame = CGRectOffset(viewToDrag.frame, translation.x, translation.y); // this is the new (moved) frame // Now this is the critical part because I don't know if your "margin" // is a CGRect or maybe some int values, the important thing here is // to compare if the "movedFrame" values are in the allowed movement area // Assuming that your margin is a CGRect you could do the following: if (CGRectContainsRect(yourPermissibleMargin, movedFrame)) { CGPoint newCenter = CGPointMake(CGRectGetMidX(movedFrame), CGRectGetMidY(movedFrame)); viewToDrag.center = newCenter; // Move your view } // -OR- // If you have your margins as int values you could do the following: if ( (movedFrame.origin.x + movedFrame.size.width) < 50) { CGPoint newCenter = CGPointMake(CGRectGetMidX(movedFrame), CGRectGetMidY(movedFrame)); viewToDrag.center = newCenter; // Move your view } } 

You may have to adapt this to suit your specific needs.

Hope this helps!

+3
source
 - (void)dragAction:(UIPanGestureRecognizer *)gesture{ UILabel *label = (UILabel *)gesture.view; CGPoint translation = [gesture translationInView:label]; if (CGRectContainsPoint(label.frame, [gesture locationInView:label] )) { label.center = CGPointMake(label.center.x, label.center.y); [gesture setTranslation:CGPointZero inView:label]; } else{ label.center = CGPointMake(label.center.x, label.center.y + translation.y); [gesture setTranslation:CGPointZero inView:label]; } } 
0
source

Here is the answer in Swift 4 - Limit the viewing movement to view

 @objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) { // Allows smooth movement of stickers. if gestureRecognizer.state == .began || gestureRecognizer.state == .changed { let point = gestureRecognizer.location(in: self.superview) if let superview = self.superview { let restrictByPoint : CGFloat = 30.0 let superBounds = CGRect(x: superview.bounds.origin.x + restrictByPoint, y: superview.bounds.origin.y + restrictByPoint, width: superview.bounds.size.width - 2*restrictByPoint, height: superview.bounds.size.height - 2*restrictByPoint) if (superBounds.contains(point)) { let translation = gestureRecognizer.translation(in: self.superview) gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y) gestureRecognizer.setTranslation(CGPoint.zero, in: self.superview) } } } } 

If you need more control over it, map the value of limitByPoint to your moving angle.

0
source

Source: https://habr.com/ru/post/950125/


All Articles