This is an automated email from the ASF dual-hosted git repository. moshen pushed a commit to branch fix-animation-cpu in repository https://gitbox.apache.org/repos/asf/incubator-weex.git
commit d951f9729d4b355049dda22c771e8abd19e49421 Author: qianyuan.wqy <[email protected]> AuthorDate: Wed Sep 11 11:04:18 2019 +0800 Fix bug that when view is not loaded or not attached to a window, the CA animation completion callback is immediately called. --- ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m | 54 ++++++++++++++++------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m index a1d78b3..8ee1591 100644 --- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m +++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m @@ -355,6 +355,21 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:)) - (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args callback:(WXModuleKeepAliveCallback)callback { + /* Check if view of targetComponent is created, if not, we do not do animation and + simulate delay of 'duration' and callback. + For a view in list, the view migth be recycled, and if view is not attached to a window, + the CATransaction completion block will be called immediately, which may cause CPU overload + problem if JS code do any logic in the completion callback. + */ + + BOOL shouldDoAnimation = NO; + if ([targetComponent isViewLoaded]) { + UIView* view = targetComponent.view; + if ([view window] != nil) { + shouldDoAnimation = YES; + } + } + /** UIView-style animation functions support the standard timing functions, but they don’t allow you to specify your own cubic Bézier curve. @@ -362,21 +377,31 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:)) **/ [CATransaction begin]; [CATransaction setAnimationTimingFunction:[WXConvert CAMediaTimingFunction:args[@"timingFunction"]]]; - [CATransaction setCompletionBlock:^{ - if (callback) { - NSDictionary *message; - if (_isAnimationedSuccess) { - message = @{@"result":@"Success", - @"message":@"Success"}; - } - else - { - message = @{@"result":@"Fail", - @"message":@"Animation did not complete"}; + + if (shouldDoAnimation) { + [CATransaction setCompletionBlock:^{ + if (callback) { + NSDictionary *message; + if (_isAnimationedSuccess) { + message = @{@"result":@"Success", + @"message":@"Success"}; + } + else + { + message = @{@"result":@"Fail", + @"message":@"Animation did not complete"}; + } + callback(message, NO); } - callback(message,NO); - } - }]; + }]; + } + else if (callback) { + double duration = [[args objectForKey:@"duration"] doubleValue] / 1000.f; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + callback(@{@"result":@"Success", + @"message":@"Success"}, NO); + }); + } BOOL needLayout = NO; WXTransition* transition = nil; @@ -387,6 +412,7 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:)) } [CATransaction commit]; + if (needLayout && transition) { WXPerformBlockOnComponentThread(^{ [transition _handleTransitionWithStyles:transitionDic resetStyles:nil target:targetComponent];
