addCoordinatedAnimations mangles scale transform animations

Since tvOS 9.2, the

addCoordinatedAnimations(-:completion:)
method of
UIFocusAnimationCoordinator
has exhibited a strange behavior. Assume you have a collection view whose cells use either affine or 3D scale transforms to scale-up their contents when focused:


override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    coordinator.addCoordinatedAnimations({
        if self.focused {
            self.focusEffectsContainer.transform = CGAffineTransformMakeScale(1.158, 1.158)
        } else {
            self.focusEffectsContainer.transform = CGAffineTransformIdentity
        }
    }, completion: nil)
}


If you scroll through the collection view very quickly, cells that acquire and then immediately lose focus before being scrolled into the visible boundswill appear to be scaled-down for a few moments before returning to their identity transform states.


Check out a video of the bug here. You can also download the sample project here.


My best guess is that UIFocusAnimationCoordinator’s

addCoordinatedAnimations
method is using some unclamped animation parameters, which causes the return to an identity transform to over-downscale (like a bouncy animation). This, in conjunction with the (new since 9.2) delay applied to coordinated animations for offscreen views, might be causing the shrunken appearance of the cells awaiting the rest of their unfocusing animations.


I can “resolve” the issue by making nested UIView animation block calls from inside the

addCoordinatedAnimations
animation block argument, passing animation options that override the inherited curve and duration. But this results in sloppy looking animations all the time, even though it resolves the fast-scrolling transform edge case. I’d prefer to find a workaround that continues to use
addCoordinatedAnimations
the way it was intended.

Replies

I see the same issue with any app (YouTube or UIKitCatalog) that has search with a keybaord. Put some text in to get some search results, and then swipe up/down fast between "ABC abc 123 #+-" and the first result. You will see it mangle "ABC abc 123 #+-", stretching it full screen quickly and then back.

I was able to fix my issue by calling [self.layer removeAllAnimations]; before coordinator.addCoordinatedAnimations.

I think I have the same issue.


If I have a table view cell with custom focus style and when scrolling through the the tableview fast, some cells will keep the old transform when being reused. I've tried setting the identity transform upon the cell being reused.


In the cell when gaining focus:

self.transform = .init(scaleX: 1.1, y: 1.1)


In the cell when losing focus:

self.transform = .identity


Is there any solution to this?