iPhone - Inertial dragging
I have an object that the user has to drag around the screen. This is a regular UIImageView. Currently, the image can be dragged around 开发者_运维百科but when you release it, it stops where your finger lifted the image. What I want is to create momentum, so I can give an impulse to the image and it scrolls until it bounces the screen edge.
I don't want nothing very complex like adding physics libraries and stuff like that. I want to keep it as minimum as possible.
How do I do that? Can you guys point me to some tutorial or in the right direction?
thanks.
Well one way of doing this without using any physics library is this:
First in your class create 4 instance variables like this:
CFTimeInterval startTime;
CGPoint startPoint;
CGPoint oldPoint;
BOOL imageViewTouched;
Than in your - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
method have this code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouched] anyObject];
// Test to see if the touched view is your image view. If not just return.
if (touch.view != <#yourImageView#>) {
return;
}
startPoint = [touch locationInView:self.view];
oldPoint = startPoint;
startTime = CACurrentMediaTime();
imageViewTouched = YES;
}
For - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
do this:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// Fingers were moved on the screen but your image view was not touched in the beginning
if (!imageViewTouched) {
return;
}
UITouch *touch = [[event allTouches] anyObject];
CGPoint newPoint = [touch locationInView:self.view];
<#yourImageView#>.frame = CGRectOffset(<#yourImageView#>.frame, newPoint.x - oldPoint.x, newPoint.y - oldPoint.y);
oldPoint = newPoint;
}
Now for - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
try this:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Fingers were removed from the screen but your image view was not touched in the beginning
if (!imageViewTouched) {
return;
}
imageViewTouched = NO;
UITouch *touch = [[event allTouches] anyObject];
CGPoint endPoint = [touch locationInView:self.view];
CFTimeInterval endTime = CACurrentMediaTime();
CFTimeInterval timeDifference = endTime - startTime;
// You may play with this value until you get your desired effect
CGFloat maxSpeed = 80;
CGFloat deltaX = 0;
CGFloat deltaY = 0;
if (timeDifference < 0.35) {
deltaX = (endPoint.x - startPoint.x) / (timeDifference * 10);
deltaY = (endPoint.y - startPoint.y) / (timeDifference * 10);
}
if (deltaX > maxSpeed) { deltaX = maxSpeed; }
else if (deltaX < -maxSpeed) { deltaX = -maxSpeed; }
else if (deltaX > -5 && deltaX < 5) { deltaX = 0; }
if (deltaY > maxSpeed) { deltaY = maxSpeed; }
else if (deltaY < -maxSpeed) { deltaY = -maxSpeed; }
else if (deltaY > -5 && deltaY < 5) { deltaY = 0; }
[UIView begginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
<#yourImageView#>.frame = CGRectOffset(<#yourImageView#>.frame, deltaX, deltaY);
[UIView commitAnimations];
}
Please let me know if this makes sense and/or works for you. Cheers!
精彩评论