2

Im animating some buttons in swift to move randomly across the view forever, however the buttons 'target' does not move. To click the button, you have to click the original position that it is created at, even though it might be the other side of the screen.

Does anyone have simple instructions for how to move the buttons target with the button?

    func circlePath(view: UIButton, pathDuration: Double){
    //create an animation to follow a circular path
    let pathAnimation: CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position")
    //interpolate the movement to be more smooth
    pathAnimation.calculationMode = kCAAnimationPaced
    pathAnimation.repeatCount = .infinity
    //no ease in/out to have the same speed along the path
    pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    //the paths circular animation is proportional its size
    pathAnimation.duration = pathDuration
    //The circle to follow will be inside the circleContainer frame.
    //it should be a frame around the center of your view to animate.
    //do not make it to large, a width/height of 3-4 will be enough.
    let curvedPath: CGMutablePathRef = CGPathCreateMutable()
    let circleContainer: CGRect = CGRectInset(view.frame, 23, 23)
    CGPathAddEllipseInRect(curvedPath, nil, circleContainer)
    //add the path to the animation
    pathAnimation.path = curvedPath
    //add animation to the view's layer
    view.layer.addAnimation(pathAnimation, forKey: "myCircleAnimation")
}

1 Answers1

1

Don't use the term "target" to mean the area that taps respond to. "Target" has a specific meaning with regard to buttons, and it's not that.

Let's call it the "hit rectangle".

Core Animation does not actually animate the objects across the screen. It creates a "presentation layer" that gives the appearance of the objects moving, but the objects themselves do not animate.

Thus you can't have buttons respond to taps while "mid-flight" in an animation.

Instead, what you have to do is to put a tap gesture recognizer on the superview (or the layer that contains the layer you're animating, if you're doing CAAnimation.) Then you can use the hitTest method of the animated layer's presentation layer to test if the tap was inside the bounds of the layer that's being animated.

I have a project on github that show this technique. It's called iOS-CAAnimation-group-demo (link.) It's written in Objective-C, but the technique is the same regardless of language so it should give you an idea of how to proceed.

Duncan C
  • 128,072
  • 22
  • 173
  • 272