ComponentKit/Core/CKMountAnimationGuard.h (41 lines of code) (raw):
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <QuartzCore/QuartzCore.h>
/** Used by CKComponent internally to block animations when configuring a new or recycled view */
class CKMountAnimationGuard {
public:
static BOOL blockAnimationsIfNeeded(id<CKMountable> oldComponent, id<CKMountable> newComponent,
const CK::Component::MountContext &ctx,
const CKComponentViewConfiguration &viewConfig) noexcept
{
if (shouldBlockAnimations(oldComponent, newComponent, ctx, viewConfig)) {
[CATransaction setDisableActions:YES];
return YES;
}
return NO;
}
static void unblockAnimation() {
[CATransaction setDisableActions:NO];
}
private:
static BOOL shouldBlockAnimations(id<CKMountable> oldComponent, id<CKMountable> newComponent,
const CK::Component::MountContext &ctx,
const CKComponentViewConfiguration &viewConfig) noexcept
{
if ([CATransaction disableActions]) {
return NO; // Already blocked
}
// If the context explicitly tells us to block animations, do it.
if (ctx.shouldBlockAnimations) {
return YES;
}
if (viewConfig.blockImplicitAnimations()) {
return YES;
}
// If we're configuring an entirely new view, or one where the old component has already unmounted,
// block animation to prevent animating from an undefined previous state.
if (oldComponent == nil) {
return YES;
}
// If we do have scope frame tokens for both the old and new components, but they don't match, block animation.
id oldUniqueIdentifier = [oldComponent uniqueIdentifier];
id newUniqueIdentifier = [newComponent uniqueIdentifier];
if (oldUniqueIdentifier && newUniqueIdentifier && ![oldUniqueIdentifier isEqual:newUniqueIdentifier]) {
return YES;
}
// Otherwise, assume we can animate!
return NO;
}
};