iphone开发-模拟drop pin的效果
iphone的地图程序(google map)中有大头针从屏幕顶部落下的效果,我们叫做drop pin。现在我来模仿一个。
红色的大头针从A点drop到B点,以针尖为参照,扎破之前的大头针高46pix,扎破之后的高42pix,所以针尖落地之后要进行相应的调整,我创建一个UIImageview* pin,然后将pin从A点drop到B点。
我写了下面的函数:
pin是我构造的一个view,大小和大头针一样大。point就是上面说的B点,duration为下落的总时间。默认采用0.5。
- (void)dropPinToPoint:(MarkerView*)pin toPoint:(CGPoint)point duration:(float)duration
{
locationPin_ = pin;
//如果B点在屏幕的外边,那么不用显示drop的过程。
if(point.x < -100 || point.x > 420 || point.y < -100 || point.y > 480)
{
GLatLng latlng;
latlng.lat = 0;
latlng.lng = 0;
CGRect frame = CGRectMake(pin.frame.origin.x, pin.frame.origin.y + 4.0, pin.frame.size.width, 42.0);
pin.frame = frame;
//pin落地后要换图,换为扎破效果的图
[pin puncture:[UIImage imageNamed:@"green_pin_puncture.png"]];
return;
}
// Bounces the placard back to the center
CALayer *pinLayer = pin.layer;
//Create a keyframe animation to follow a path back to the center
CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
bounceAnimation.removedOnCompletion = NO;
// Create the path for the bounces
CGMutablePathRef thePath = CGPathCreateMutable();
CGFloat midX = point.x;
CGFloat midY = point.y - pin.frame.size.height/2.0;
float animationDuration = duration;//0.5
// Start the path at the pin's current location
CGPathMoveToPoint(thePath, NULL, pin.center.x, pin.center.y);
CGPathAddLineToPoint(thePath, NULL, midX, midY);
CGPathAddLineToPoint(thePath, NULL, midX, midY - 5.0);
CGPathAddLineToPoint(thePath, NULL, midX, midY);
bounceAnimation.path = thePath;
bounceAnimation.duration = animationDuration;
// Create a basic animation to restore the size of the pin
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.removedOnCompletion = YES;
transformAnimation.duration = animationDuration;
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
// Create an animation group to combine the keyframe and basic animations
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
// Set self as the delegate to allow for a callback to reenable user interaction
theGroup.delegate = self;
theGroup.duration = animationDuration;
theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
theGroup.animations = [NSArray arrayWithObjects:bounceAnimation, transformAnimation, nil];
// Add the animation group to the layer
[pinLayer addAnimation:theGroup forKey:@"dropPinToPoint"];
// Set the placard view's center and transformation to the original values in preparation for the end of the animation
pin.center = CGPointMake(midX, midY);
pin.transform = CGAffineTransformIdentity;
CGRect frame = CGRectMake(pin.frame.origin.x, pin.frame.origin.y + 4.0, pin.frame.size.width, 42.0);
pin.frame = frame;
// Get lower location of the marker
[self bringSubviewToFront:pin];
bLocationPinAnimate_ = YES;
}
上面执行的是一个动画,那么动画结束后就会执行下面的函数,在下面的函数里面给刚才落地的pin换图
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
if(bLocationPinAnimate_){
if(locationPin_){
[locationPin_ puncture:[UIImage imageNamed:@"green_pin_puncture.png"]];
bLocationPinAnimate_ = NO;
}
}
}
- (void) puncture:(UIImage*)image{
image_.image = image;
image_.frame = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height);
}