Pulse ring animation around a Google Maps marker iOS

6.2k views Asked by At

I want to add a pulse ring animation around a marker as a current user location in iOS google maps (like Uber). I tried with adding CABasicAnimation to marker layer by addAnimation. It is not working.

Also I tried animate the scale of the marker but the scale change did not happen. Can anybody help me with this thing?

1

There are 1 answers

12
Antony Raphel On BEST ANSWER

somehow it is working now. I created a custom view and set that view into GMSMarker iconView. After that added animation into view layer.

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
view.backgroundColor = [UIColor redColor];
view.layer.cornerRadius = 50;

GMSMarker *m = [GMSMarker markerWithPosition:mapView_.myLocation.coordinate];
m.iconView = view;
m.map = mapView_;


CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.duration = 1.5;
scaleAnimation.repeatCount = HUGE_VAL;
scaleAnimation.autoreverses = YES;
scaleAnimation.fromValue = [NSNumber numberWithFloat:0.1];
scaleAnimation.toValue = [NSNumber numberWithFloat:1.2];

[view.layer addAnimation:scaleAnimation forKey:@"scale"];

Another method:


GMSMarker *m = [GMSMarker markerWithPosition:mapView_.myLocation.coordinate];

//custom marker image
    UIImageView *pulseRingImg = [[UIImageView alloc] initWithFrame: CGRectMake(-30, -30, 78, 78)];
    pulseRingImg.image = [UIImage imageNamed:@"Pulse"];
    pulseRingImg.userInteractionEnabled = NO;


    //transform scale animation
    CABasicAnimation *theAnimation;
    theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
    theAnimation.duration = 3.5;
    theAnimation.repeatCount = HUGE_VALF;
    theAnimation.autoreverses = NO;
    theAnimation.fromValue = [NSNumber numberWithFloat:0.0];
    theAnimation.toValue = [NSNumber numberWithFloat:2.0];

//alpha Animation for the image
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
    animation.duration = 3.5;
    animation.repeatCount = HUGE_VALF;
    animation.values = [NSArray arrayWithObjects:
                       [NSNumber numberWithFloat:1.0],
                       [NSNumber numberWithFloat:0.5],
                       [NSNumber numberWithFloat:0.0], nil];
    animation.keyTimes = [NSArray arrayWithObjects:
                         [NSNumber numberWithFloat:0.0],
                         [NSNumber numberWithFloat:1.2],
                         [NSNumber numberWithFloat:3.5], nil];
    [pulseRingImg.layer addAnimation:animation forKey:@"opacity"];


    [pulseRingImg.layer addAnimation:theAnimation forKey:@"pulse"];
    pulseRingImg.userInteractionEnabled = NO;

    m.iconView = pulseRingImg;
    [m.layer addSublayer:pulseRingImg.layer];
    m.map = mapView_;
    m.groundAnchor = CGPointMake(0.5, 0.5);

Another one:

m = [GMSMarker markerWithPosition:mapView_.myLocation.coordinate];

    //custom marker image
    UIImageView *pulseRingImg = [[UIImageView alloc] initWithFrame: CGRectMake(-30, -30, 78, 78)];
    pulseRingImg.image = [UIImage imageNamed:@"Pulse"];
    pulseRingImg.userInteractionEnabled = NO;

    float duration = 3.5f;

    [CATransaction begin];
    [CATransaction setAnimationDuration: duration];

    //transform scale animation
    CABasicAnimation *theAnimation;
    theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
    theAnimation.repeatCount = HUGE_VALF;
    theAnimation.autoreverses = NO;
    theAnimation.fromValue = [NSNumber numberWithFloat:0.0];
    theAnimation.toValue = [NSNumber numberWithFloat:2.0];

    [pulseRingImg.layer addAnimation:theAnimation forKey:@"pulse"];
    pulseRingImg.userInteractionEnabled = NO;

    [CATransaction setCompletionBlock:^{
        //alpha Animation for the image
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
        animation.duration = duration;
        animation.repeatCount = HUGE_VALF;
        animation.values = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:1.0],
                            [NSNumber numberWithFloat:0.0], nil];
        [m.iconView.layer addAnimation:animation forKey:@"opacity"];
    }];

    [CATransaction commit];

    m.iconView = pulseRingImg;
    [m.layer addSublayer:pulseRingImg.layer];
    m.map = mapView_;
    m.groundAnchor = CGPointMake(0.5, 0.5);

Swift 3.0 code is below NOTE: Change the duration based on your requirement

           let m = GMSMarker(position: camera.target)

            //custom marker image
            let pulseRingImg = UIImageView(frame: CGRect(x: -30, y: -30, width: 78, height: 78))
            pulseRingImg.image = UIImage(named: "Pulse")
            pulseRingImg.isUserInteractionEnabled = false
            CATransaction.begin()
            CATransaction.setAnimationDuration(3.5)

            //transform scale animation
            var theAnimation: CABasicAnimation?
            theAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
            theAnimation?.repeatCount = Float.infinity
            theAnimation?.autoreverses = false
            theAnimation?.fromValue = Float(0.0)
            theAnimation?.toValue = Float(2.0)
            theAnimation?.isRemovedOnCompletion = false

            pulseRingImg.layer.add(theAnimation!, forKey: "pulse")
            pulseRingImg.isUserInteractionEnabled = false
            CATransaction.setCompletionBlock({() -> Void in

                //alpha Animation for the image
                let animation = CAKeyframeAnimation(keyPath: "opacity")
                animation.duration = 3.5
                animation.repeatCount = Float.infinity
                animation.values = [Float(2.0), Float(0.0)]
                m.iconView?.layer.add(animation, forKey: "opacity")
            })

            CATransaction.commit()
            m.iconView = pulseRingImg
            m.layer.addSublayer(pulseRingImg.layer)
            m.map = gmapView
            m.groundAnchor = CGPoint(x: 0.5, y: 0.5)

pulse Image: pulse image for animation