Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Add new APIs for implicit animations. #30

Merged
merged 10 commits into from
Nov 6, 2017
Merged

Add new APIs for implicit animations. #30

merged 10 commits into from
Nov 6, 2017

Conversation

jverkoey
Copy link
Contributor

@jverkoey jverkoey commented Nov 6, 2017

Example usage:

animator.animate(with: timing) {
  self.view.frame = .init(x: 0, y: 0, width: 100, height: 100)
}

This new API works similarly to UIView's animate(withDuration:...) family of APIs. This new API enables the following key features:

  1. Familiarity. UIKit's animate(withDuration:...) is a familiar, concise API for doing in-place animations.
  2. Flexibility. Implicit animations support cascading value changes, something that explicit animations can't easily do. For example, animating a view's frame will generate both a position and a bounds animation. Using the explicit APIs would require animating each of those properties individually.

@jverkoey jverkoey requested review from randallli and romoore November 6, 2017 19:22
Copy link
Contributor

@romoore romoore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Halfway through, some initial feedback.

Performs `animations` using the timing provided.

@param timing The timing to be used for the animation.
@param animations The block to be executed. Any animatable properties changed within this block
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we document the retain semantics of the block for callers? Is it as safe (unretained) as UIKit animations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

*/
- (void)animateWithTiming:(MDMMotionTiming)timing
animations:(nonnull void (^)(void))animations
completion:(nonnull void(^)(void))completion;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to see a single API with a nullable completion block. CATransaction allows a nullable completionBlock parameter, so we can reuse the same code.

+ (void)setCompletionBlock:(nullable void (^)(void))block;

— CATransaction.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is keeping in line with UIView's APIs of similar naming, so I'm not certain that we should deviate or encourage use of CATransaction (which is intended primarily for use with explicit animations)

@property(nonatomic, strong, readonly) CALayer *layer;
@end

NSArray<MDMImplicitAction *> *MDMAnimateBlock(void (^work)(void));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Maybe name the block parameter "animations"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

static IMP sOriginalActionForLayerImp = NULL;

@interface MDMActionContext: NSObject
@property(nonatomic, strong, readonly) NSArray<MDMImplicitAction *> *actions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this array be copy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

- (NSArray<MDMImplicitAction *> *)actions {
return _actions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please return a copy, since the array is mutable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


MDMActionContext *context = [sActionContext lastObject];

if (context == nil) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really nitty-gritty code. It would help me immensely to provide some comments to help guide me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

MDMActionContext *context = [sActionContext lastObject];

if (context == nil) {
return ((id<CAAction>(*)(id,SEL,CALayer *, NSString *))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Spacing between id,SEL,CALayer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
[sActionContext addObject:[[MDMActionContext alloc] init]];

work();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please perform a nil check before invoking this block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nil guard is at the top of this method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, sorry. "Ack."

}
[sActionContext addObject:[[MDMActionContext alloc] init]];

work();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, sorry. "Ack."


CATransaction.commit()

XCTAssertEqual(addedAnimations.count, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also XCTAssert the view's alpha is immediately set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@jverkoey jverkoey merged commit 1793979 into develop Nov 6, 2017
@jverkoey jverkoey deleted the implicit branch November 6, 2017 21:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants