Reputation: 33644
I am unsure why this doesn't pan when I move the view?
CGPoint translation = [recognizer translationInView:self.view];
if ((recognizer.view.frameY + translation.y >= self.view.frameHeight - recognizer.view.frameHeight)) {
CGPoint newOrigin = CGPointMake(self.view.bounds.size.width, roundf(recognizer.view.frameY + translation.y));
recognizer.view.frameOrigin = newOrigin;
NSLog(@"FRAME ORIGIN %@", NSStringFromCGPoint(recognizer.view.frameOrigin));
}
Upvotes: 3
Views: 2893
Reputation: 437492
I was unclear as to some of your custom variables and the like, so rather than debugging your code, I thought I'd show you how I'd do the dragging of a view using a UIPanGestureRecognizer
.
Thus, assuming (a) the gesture has been added to the view being dragged; and (b) that view is contained within a superview that you want to constrain the movement of the view, the code might look like:
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
static CGRect originalFrame;
if (gesture.state == UIGestureRecognizerStateBegan)
{
originalFrame = gesture.view.frame;
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
CGPoint translate = [gesture translationInView:gesture.view.superview];
CGRect newFrame = CGRectMake(originalFrame.origin.x + translate.x,
originalFrame.origin.y + translate.y,
originalFrame.size.width,
originalFrame.size.height);
if (CGRectContainsRect(gesture.view.superview.bounds, newFrame))
gesture.view.frame = newFrame;
}
}
While the above enjoys a certain simplicity, I think we can improve upon the user experience. Notably, the above code will not do anything if the user drags the view outside of it's superview (e.g. drag past the left border and it freezes there, even as you move your finger up and down; not very elegant). I think that the following is a more graceful user interface (but a tiny bit more complicated to read the code), where as the user drags their finger, we'll drag the object to the closest point in the superview that corresponds to where the user's finger is.
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
static CGRect originalFrame;
if (gesture.state == UIGestureRecognizerStateBegan)
{
originalFrame = gesture.view.frame;
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
CGPoint translate = [gesture translationInView:gesture.view.superview];
CGRect newFrame = CGRectMake(fmin(gesture.view.superview.frame.size.width - originalFrame.size.width, fmax(originalFrame.origin.x + translate.x, 0.0)),
fmin(gesture.view.superview.frame.size.height - originalFrame.size.height, fmax(originalFrame.origin.y + translate.y, 0.0)),
originalFrame.size.width,
originalFrame.size.height);
gesture.view.frame = newFrame;
}
}
Upvotes: 6
Reputation: 2002
Did pan gesture method called? if not set user interaction enabled. you can use below code.
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:recognizer.view.superview];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:recognizer.view.superview];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:recognizer.view.superview];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), recognizer.view.superview.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), recognizer.view.superview.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
Upvotes: 1
Reputation: 7343
In the if
you should write <=
instead of >=
, since the origin is in the upper left corner
Upvotes: 0