Search code examples
iosswiftcore-animation

Why does repeating UIView animation freeze on edge swipe?


I'm attempting to make a view that continuously scrolls an image from right to left, effectively creating a background that scrolls indefinitely. I've built this using two image views next to each other, and using a UIView animation set to .Repeat that translates the frames with a negative horizontal offset. (code below)

It works great! Until I attempt an edge swipe in navigation controller, at which point the animation freezes:

animation freezing on edge swipe

My code looks like:

class ScrollingImageView: UIView {
    required init?(coder aDecoder: NSCoder) { fatalError() }

    let imageView = UIImageView()
    let imageView2 = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)


        imageView.image = UIImage(named: "mario")
        imageView2.image = UIImage(named: "mario")

        imageView.frame = bounds
        imageView2.frame = CGRectOffset(bounds, bounds.width, 0)

        addSubview(imageView)
        addSubview(imageView2)
    }

    func play() {
        UIView.animateWithDuration(5, delay: 0, options: [.Repeat, .CurveLinear], animations: {
            self.imageView.frame = CGRectOffset(self.imageView.frame, -self.bounds.width, 0)
            self.imageView2.frame = CGRectOffset(self.imageView2.frame, -self.bounds.width, 0)
        }, completion: nil)
    }
}

Why does the animation stop when this interaction begins? I'm thinking it has something to do with the interactive gesture setting the speed on the CALayer to zero. Is there a way to make this animation keep playing?


Solution

  • As you rightly say, you're using an interactive gesture. How does it work? It freezes the animation (layer speed is zero) and changes its "frame" (layer timeOffset) to match the current location of the gesture.

    To work around this, you could perhaps put the animation into a different layer, though I'm not sure about that. The way that I'm sure would work would be to implement the entire custom transition interaction yourself — not using the UIPercentDrivenInteractiveTransition (which freezes the animation) but positioning the view yourself as the transition proceeds.