Add old transition API back but allow call from background thread (#2135)

This commit is contained in:
Michael Schneider 2016-09-01 16:09:59 -07:00 committed by Adlai Holler
parent 7ef6c0ff2c
commit f8e135a1be
6 changed files with 43 additions and 93 deletions

View File

@ -115,35 +115,13 @@
[self didRelayoutFromOldSize:oldSize toNewSize:self.calculatedSize];
}
- (void)transitionLayoutAnimated:(BOOL)animated
measurementCompletion:(void (^)())completion
{
CGSize oldSize = self.calculatedSize;
[super transitionLayoutAnimated:animated
measurementCompletion:^{
[self didRelayoutFromOldSize:oldSize toNewSize:self.calculatedSize];
if (completion) {
completion();
}
}
];
}
//Deprecated
- (void)transitionLayoutWithAnimation:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(void(^)())completion
{
[self transitionLayoutAnimated:animated measurementCompletion:completion];
}
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
animated:(BOOL)animated
measurementCompletion:(void (^)())completion
{
CGSize oldSize = self.calculatedSize;
[super transitionLayoutWithSizeRange:constrainedSize
animated:animated
[super transitionLayoutWithAnimation:animated
shouldMeasureAsync:shouldMeasureAsync
measurementCompletion:^{
[self didRelayoutFromOldSize:oldSize toNewSize:self.calculatedSize];
if (completion) {
@ -153,13 +131,22 @@
];
}
//Deprecated
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
animated:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(void(^)())completion
{
[self transitionLayoutWithSizeRange:constrainedSize animated:animated measurementCompletion:completion];
CGSize oldSize = self.calculatedSize;
[super transitionLayoutWithSizeRange:constrainedSize
animated:animated
shouldMeasureAsync:shouldMeasureAsync
measurementCompletion:^{
[self didRelayoutFromOldSize:oldSize toNewSize:self.calculatedSize];
if (completion) {
completion();
}
}
];
}
- (void)didRelayoutFromOldSize:(CGSize)oldSize toNewSize:(CGSize)newSize

View File

@ -54,47 +54,6 @@
*/
- (void)loadStateDidChange:(BOOL)inLoadState ASDISPLAYNODE_REQUIRES_SUPER ASDISPLAYNODE_DEPRECATED;
/**
* @abstract Transitions the current layout with a new constrained size. Must be called on main thread.
*
* @param animated Animation is optional, but will still proceed through your `animateLayoutTransition` implementation with `isAnimated == NO`.
* @param shouldMeasureAsync Measure the layout asynchronously.
* @param measurementCompletion Optional completion block called only if a new layout is calculated.
* It is called on main, right after the measurement and before -animateLayoutTransition:.
*
* @discussion If the passed constrainedSize is the the same as the node's current constrained size, this method is noop.
*
* @see animateLayoutTransition:
*
* @deprecated Deprecated in version 2.0: Use transitionLayoutWithSizeRange:animated:measurementCompletion:.
* shouldMeasureAsync is enabled by default now.
*
*/
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
animated:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(nullable void(^)())completion ASDISPLAYNODE_DEPRECATED;
/**
* @abstract Invalidates the current layout and begins a relayout of the node with the current `constrainedSize`. Must be called on main thread.
*
* @discussion It is called right after the measurement and before -animateLayoutTransition:.
*
* @param animated Animation is optional, but will still proceed through your `animateLayoutTransition` implementation with `isAnimated == NO`.
* @param shouldMeasureAsync Measure the layout asynchronously.
* @param measurementCompletion Optional completion block called only if a new layout is calculated.
*
* @see animateLayoutTransition:
*
* @deprecated Deprecated in version 2.0: Use transitionLayoutAnimated:measurementCompletion:
* shouldMeasureAsync is enabled by default now.
*
*/
- (void)transitionLayoutWithAnimation:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(nullable void(^)())completion ASDISPLAYNODE_DEPRECATED;
/**
* @abstract Cancels all performing layout transitions. Can be called on any thread.
*

View File

@ -782,27 +782,34 @@ NS_ASSUME_NONNULL_BEGIN
* @param animated Animation is optional, but will still proceed through your `animateLayoutTransition` implementation with `isAnimated == NO`.
* @param shouldMeasureAsync Measure the layout asynchronously.
* @param measurementCompletion Optional completion block called only if a new layout is calculated.
* It is called on main, right after the measurement and before -animateLayoutTransition:.
*
* @discussion It is called on main, right after the measurement and before -animateLayoutTransition:. If the passed constrainedSize is the the same as the node's current constrained size, this method is noop.
* @discussion If the passed constrainedSize is the the same as the node's current constrained size, this method is noop. If passed YES to shouldMeasureAsync it's guaranteed that measurement is happening on a background thread, otherwise measaurement will happen on the thread that the method was called on. The measurementCompletion callback is always called on the main thread right after the measurement and before -animateLayoutTransition:.
*
* @see animateLayoutTransition:
*
*/
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
animated:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(nullable void(^)())completion;
/**
* @abstract Invalidates the current layout and begins a relayout of the node with the current `constrainedSize`. Must be called on main thread.
*
* @discussion It is called right after the measurement and before -animateLayoutTransition:.
*
* @param animated Animation is optional, but will still proceed through your `animateLayoutTransition` implementation with `isAnimated == NO`.
* @param shouldMeasureAsync Measure the layout asynchronously.
* @param measurementCompletion Optional completion block called only if a new layout is calculated.
*
* @see animateLayoutTransition:
*
*/
- (void)transitionLayoutAnimated:(BOOL)animated measurementCompletion:(nullable void(^)())completion;
- (void)transitionLayoutWithAnimation:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(nullable void(^)())completion;
/**
* @abstract Cancels all performing layout transitions. Can be called on any thread.

View File

@ -723,7 +723,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
#pragma mark - Layout Transition
- (void)transitionLayoutAnimated:(BOOL)animated measurementCompletion:(void (^)())completion
- (void)transitionLayoutWithAnimation:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(void(^)())completion
{
if (_calculatedLayout == nil) {
// constrainedSizeRange returns a struct and is invalid to call on nil.
@ -734,15 +736,18 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
[self invalidateCalculatedLayout];
[self transitionLayoutWithSizeRange:_calculatedLayout.constrainedSizeRange
animated:animated
shouldMeasureAsync:shouldMeasureAsync
measurementCompletion:completion];
}
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
animated:(BOOL)animated
measurementCompletion:(void (^)())completion
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(void(^)())completion
{
ASDisplayNodeAssertMainThread();
if (! [self shouldMeasureWithSizeRange:constrainedSize]) {
// Passed constrainedSize is the the same as the node's current constrained size it's a noop
if ([self shouldMeasureWithSizeRange:constrainedSize] == NO) {
return;
}
@ -759,7 +764,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
node.pendingTransitionID = transitionID;
});
ASPerformBlockOnBackgroundThread(^{
void (^transitionBlock)(void) = ^{
if ([self _shouldAbortTransitionWithID:transitionID]) {
return;
}
@ -821,7 +827,13 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
// Kick off animating the layout transition
[self animateLayoutTransition:_pendingLayoutTransitionContext];
});
});
};
if (shouldMeasureAsync) {
ASPerformBlockOnBackgroundThread(transitionBlock);
} else {
transitionBlock();
}
}
- (void)cancelLayoutTransition
@ -3317,21 +3329,6 @@ static const char *ASDisplayNodeAssociatedNodeKey = "ASAssociatedNode";
@implementation ASDisplayNode (Deprecated)
- (void)transitionLayoutWithAnimation:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(void(^)())completion
{
[self transitionLayoutAnimated:animated measurementCompletion:completion];
}
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
animated:(BOOL)animated
shouldMeasureAsync:(BOOL)shouldMeasureAsync
measurementCompletion:(void(^)())completion
{
[self transitionLayoutWithSizeRange:constrainedSize animated:animated measurementCompletion:completion];
}
- (void)cancelLayoutTransitionsInProgress
{
[self cancelLayoutTransition];

View File

@ -126,7 +126,7 @@
XCTestExpectation *expectation = [self expectationWithDescription:@"Call measurement completion block on main"];
[displayNode transitionLayoutWithSizeRange:ASSizeRangeMake(CGSizeZero, CGSizeZero) animated:YES measurementCompletion:^{
[displayNode transitionLayoutWithSizeRange:ASSizeRangeMake(CGSizeZero, CGSizeZero) animated:YES shouldMeasureAsync:YES measurementCompletion:^{
XCTAssertTrue(ASDisplayNodeThreadIsMain(), @"Measurement completion block should be called on main thread");
[expectation fulfill];
}];
@ -207,7 +207,7 @@
node.layoutState = @2;
[node invalidateCalculatedLayout];
[node transitionLayoutAnimated:YES measurementCompletion:^{
[node transitionLayoutWithAnimation:YES shouldMeasureAsync:YES measurementCompletion:^{
// Push this to the next runloop to let async insertion / removing of nodes finished before checking
dispatch_async(dispatch_get_main_queue(), ^{
XCTAssertEqual(node.subnodes[0], node2);

View File

@ -89,7 +89,7 @@
{
self.enabled = !self.enabled;
[self transitionLayoutAnimated:YES measurementCompletion:nil];
[self transitionLayoutWithAnimation:YES shouldMeasureAsync:NO measurementCompletion:nil];
}