You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@weex.apache.org by GitBox <gi...@apache.org> on 2018/08/02 09:14:18 UTC

[GitHub] YorkShen closed pull request #1326: [WEEX-502][iOS] Weex Template List Support Animation & queryElement

YorkShen closed pull request #1326: [WEEX-502][iOS] Weex Template List Support Animation & queryElement
URL: https://github.com/apache/incubator-weex/pull/1326
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
index e3721be173..ee93eeaed3 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
@@ -26,8 +26,6 @@ static const NSString *WXDefaultRecycleTemplateType = @"default";
 @property (nonatomic, strong) NSString *templateCaseType;
 
 - (void)updateCellData:(NSDictionary *)data;
-
 - (void)triggerLayout;
 
-
 @end
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm
index 8e2aa8dd07..53db417de6 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm
@@ -40,7 +40,7 @@ - (instancetype)initWithRef:(NSString *)ref
         if (attributes[@"default"]) {
             _templateCaseType = @"default";
         }
-        _templateCaseType = attributes[@"case"] ? [WXConvert NSString:attributes[@"case"]] :const_cast<NSString *>(WXDefaultRecycleTemplateType) ;
+        _templateCaseType = attributes[@"case"] ? [WXConvert NSString:attributes[@"case"]] :const_cast<NSString *>(WXDefaultRecycleTemplateType);
         _lazyCreateView = YES;
         _isNeedJoinLayoutSystem = NO;
     }
@@ -55,9 +55,9 @@ - (void)updateAttributes:(NSDictionary *)attributes
 
 - (void)updateCellData:(NSDictionary *)data
 {
-    WXAssertComponentThread();    
-    
+    WXAssertComponentThread();
     [self updateBindingData:data];
+    [self _attachSlotEvent:data];
     [self triggerLayout];
 }
 
@@ -69,21 +69,16 @@ - (void)_didInserted
 - (void)triggerLayout
 {
     WXAssertComponentThread();
-
-        if (flexIsUndefined(self.flexCssNode->getStyleWidth())) {
-            self.flexCssNode->setStyleWidth(((WXScrollerComponent *)(self.supercomponent)).flexScrollerCSSNode->getStyleWidth(),NO);
-        }
-        
-        if ([self needsLayout]) {
-            std::pair<float, float> renderPageSize;
-            renderPageSize.first = self.weexInstance.frame.size.width;
-            renderPageSize.second = self.weexInstance.frame.size.height;
-            self.flexCssNode->calculateLayout(renderPageSize);
-            if ([WXLog logLevel] >= WXLogLevelDebug) {
-                
-            }
-        }
+    if (flexIsUndefined(self.flexCssNode->getStyleWidth())) {
+        self.flexCssNode->setStyleWidth(((WXScrollerComponent *)(self.supercomponent)).flexScrollerCSSNode->getStyleWidth(),NO);
+    }
     
+    if ([self needsLayout]) {
+        std::pair<float, float> renderPageSize;
+        renderPageSize.first = self.weexInstance.frame.size.width;
+        renderPageSize.second = self.weexInstance.frame.size.height;
+        self.flexCssNode->calculateLayout(renderPageSize);
+    }
     NSMutableSet<WXComponent *> *dirtyComponents = [NSMutableSet set];
     [self _calculateFrameWithSuperAbsolutePosition:CGPointZero gatherDirtyComponents:dirtyComponents];
     for (WXComponent *dirtyComponent in dirtyComponents) {
@@ -92,5 +87,4 @@ - (void)triggerLayout
         }];
     }
 }
-
 @end
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
index 3bbcfe6b12..22b39acef8 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
@@ -89,44 +89,46 @@ - (void)updateBindingData:(NSDictionary *)data
         return;
     }
     
-    if (templateComponent->_bindingProps) {
-        __block NSMutableDictionary *newData = [NSMutableDictionary dictionary];
-        [templateComponent->_bindingProps enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, WXDataBindingBlock  _Nonnull block, BOOL * _Nonnull stop) {
-            BOOL needUpdate;
-            id value = block(data, &needUpdate);
-            if (value) {
-                newData[key] = value;
-            }
-        }];
-        
-        if (self.attributes[@"@isComponentRoot"]) {
-            if (![recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath]) {
-                static NSUInteger __componentId = 0;
-                self->_virtualComponentId = [NSString stringWithFormat:@"%@%lu", listRef, (unsigned long)__componentId % (2048*1024)];
-                __componentId++;
-                dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
-                [[WXSDKManager bridgeMgr] callComponentHook:self.weexInstance.instanceId componentId:self.attributes[@"@templateId"] type:@"lifecycle" hook:@"create" args:@[self->_virtualComponentId, newData] competion:^(JSValue *value) {
-                    [newData addEntriesFromDictionary:[value toDictionary][@"0"]];
-                    [newData setObject:indexPath forKey:@"indexPath"];
-                    [newData setObject:listRef forKey:@"recycleListComponentRef"];
-                    [[recycleListComponent dataManager] updateVirtualComponentData:self->_virtualComponentId data:newData];
-                    dispatch_semaphore_signal(semaphore);
-                }];
-                dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
-                
-                [[WXSDKManager bridgeMgr] callComponentHook:self.weexInstance.instanceId componentId:self->_virtualComponentId type:@"lifecycle" hook:@"attach" args:nil competion:nil];
-                if ([newData count]) {
-                    data = newData;
-                }
-            } else {
-                newData[@"componentDataId"] = self->_virtualComponentId;
-                NSDictionary * virtualComponentData = [recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath];
-                [newData addEntriesFromDictionary:virtualComponentData];
-                [newData addEntriesFromDictionary:data];
+    __block NSMutableDictionary *newData = [NSMutableDictionary dictionary];
+    [templateComponent->_bindingProps enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, WXDataBindingBlock  _Nonnull block, BOOL * _Nonnull stop) {
+        BOOL needUpdate;
+        id value = block(data, &needUpdate);
+        if (value) {
+            newData[key] = value;
+        }
+    }];
+    
+    if (self.attributes[@"@isComponentRoot"]) {
+        if (![recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath]) {
+            static NSUInteger __componentId = 0;
+            self->_virtualComponentId = [NSString stringWithFormat:@"%@@%lu", listRef, (unsigned long)__componentId % (2048*1024)];
+            __componentId++;
+            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+            [[WXSDKManager bridgeMgr] callComponentHook:self.weexInstance.instanceId componentId:self.attributes[@"@templateId"] type:@"lifecycle" hook:@"create" args:@[self->_virtualComponentId, newData] competion:^(JSValue *value) {
+                [newData addEntriesFromDictionary:[value toDictionary][@"0"]];
+                [newData setObject:indexPath forKey:@"indexPath"];
+                [newData setObject:listRef forKey:@"recycleListComponentRef"];
+                [[recycleListComponent dataManager] updateVirtualComponentData:self->_virtualComponentId data:newData];
+                dispatch_semaphore_signal(semaphore);
+            }];
+            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
+            
+            [self _refsConventFromData:newData];
+            NSIndexPath *indexPath = newData[@"item"][@"indexPath"];
+            NSUInteger position = [indexPath indexAtPosition:1];
+            [[WXSDKManager bridgeMgr] callComponentHook:self.weexInstance.instanceId componentId:self->_virtualComponentId type:@"lifecycle" hook:@"attach" args:@[@{@"virtualComponentId":self->_virtualComponentId,@"position":@(position),@"refs":self->_virtalElementInfo[@"refs"]?:@{}}] competion:nil];
+            if ([newData count]) {
                 data = newData;
             }
+        } else {
+            newData[@"componentDataId"] = self->_virtualComponentId;
+            NSDictionary * virtualComponentData = [recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath];
+            [newData addEntriesFromDictionary:virtualComponentData];
+            [newData addEntriesFromDictionary:data];
+            data = newData;
         }
     }
+    
     if (phase) {
         NSMutableDictionary * newData = [data mutableCopy];
         newData[@"@phase"] = phase;
@@ -532,4 +534,71 @@ - (WXDataBindingBlock)bindingBlockWithExpression:(WXJSExpression *)expression
     return block;
 }
 
+- (void)_attachSlotEvent:(NSDictionary *)data
+{
+    [self _refsConventFromData:data];
+    if (_virtalElementInfo.count != 0) {
+        NSIndexPath *indexPath = data[@"item"][@"indexPath"];
+        NSUInteger position = [indexPath indexAtPosition:1];
+        [_virtalElementInfo addEntriesFromDictionary:@{@"position":@(position)}];
+        [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId ref:data[@"item"][@"recycleListComponentRef"] type:@"_attach_slot" params:_virtalElementInfo domChanges:nil handlerArguments:nil];
+    }
+}
+
+- (void)_detachSlotEvent:(NSDictionary *)data
+{
+    [self _refsConventFromData:data];
+    if (_virtalElementInfo.count != 0) {
+        NSIndexPath *indexPath = data[@"item"][@"indexPath"];
+        NSUInteger position = [indexPath indexAtPosition:1];
+        [_virtalElementInfo addEntriesFromDictionary:@{@"position":@(position)}];
+        [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId ref:data[@"item"][@"recycleListComponentRef"] type:@"_detach_slot" params:_virtalElementInfo domChanges:nil handlerArguments:nil];
+    }
+}
+
+- (void )_refsConventFromData:(NSDictionary *)data
+{
+    _virtalElementInfo = [NSMutableDictionary new];
+    if (self.attributes[@"ref"]) {
+        NSMutableDictionary *subInfo = [NSMutableDictionary new];
+        [self _componentInfoOfRef:self subInfo:subInfo data:data];
+        [self _recursiveSlotComponent:self subInfo:subInfo data:data];
+    }
+    else
+    {
+        [self _recursiveSlotComponent:self subInfo:nil data:data];
+    }
+}
+
+- (void)_recursiveSlotComponent:(WXComponent *)component subInfo:(NSMutableDictionary *)subInfo data:(NSDictionary *)data
+{
+    subInfo = subInfo ? : [NSMutableDictionary new];
+    for (WXComponent *subcomponent in component.subcomponents) {
+        if (subcomponent.subcomponents.count != 0) {
+            [self _recursiveSlotComponent:subcomponent subInfo:subInfo data:data];
+        }
+        [self _componentInfoOfRef:subcomponent subInfo:subInfo data:data];
+    }
+    if (subInfo.count !=0) {
+        [_virtalElementInfo setObject:subInfo forKey:@"refs"];
+    }
+}
+
+- (void)_componentInfoOfRef:(WXComponent *)component subInfo:(NSMutableDictionary *)subInfo data:(NSDictionary *)data
+{
+    if (component.attributes[@"ref"]) {
+        NSIndexPath *indexPath = data[@"item"][@"indexPath"];
+        NSUInteger position = [indexPath indexAtPosition:1];
+        NSString *virtalElementInfo = [NSString stringWithFormat:@"%@@%lu",component.ref,position];
+        NSDictionary *refInfo = @{@"attrs":component.attributes,@"type":component->_type,@"ref":virtalElementInfo,@"[[VirtualElement]]":@"true"};
+        if (subInfo[component.attributes[@"ref"]]) {
+            [subInfo[component.attributes[@"ref"]] addObject:refInfo];
+        }
+        else
+        {
+            [subInfo setValue:@[refInfo] forKey:component.attributes[@"ref"]];
+        }
+    }
+}
+
 @end
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
index e4be61722f..62decc0879 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
@@ -29,6 +29,4 @@
 @property(nonatomic, strong) WXRecycleListDataManager *dataManager;
 @property(nonatomic, strong) WXRecycleListTemplateManager *templateManager;
 @property(nonatomic, strong) WXRecycleListUpdateManager *updateManager;
-
-
 @end
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm
index a55dada8fa..3fed198d93 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm
@@ -33,6 +33,7 @@
 #import "WXSDKManager.h"
 #import "WXComponent+DataBinding.h"
 #import "WXComponent+Layout.h"
+#import "WXModuleProtocol.h"
 
 @interface WXRecycleListComponentView:UICollectionView
 @end
@@ -73,9 +74,13 @@ @implementation WXRecycleListComponent
 WX_EXPORT_METHOD(@selector(updateData:data:))
 WX_EXPORT_METHOD(@selector(removeData:count:))
 WX_EXPORT_METHOD(@selector(moveData:toIndex:))
-WX_EXPORT_METHOD(@selector(scrollTo:options:))
 WX_EXPORT_METHOD(@selector(insertRange:range:))
 WX_EXPORT_METHOD(@selector(setListData:))
+WX_EXPORT_METHOD(@selector(scrollTo:options:))
+WX_EXPORT_METHOD(@selector(scrollToElement:options:))
+WX_EXPORT_METHOD(@selector(queryElement:cssSelector:callback:))
+WX_EXPORT_METHOD(@selector(queryElementAll:cssSelector:callback:))
+WX_EXPORT_METHOD(@selector(closest:cssSelector:callback:))
 
 - (instancetype)initWithRef:(NSString *)ref
                        type:(NSString *)type
@@ -370,25 +375,154 @@ - (void)moveData:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex
     }];
 }
 
-- (void)scrollTo:(NSUInteger)index options:(NSDictionary *)options
+- (void)scrollTo:(NSString *)virtalElementInfo options:(NSDictionary *)options
 {
-    NSIndexPath *toIndexPath = [NSIndexPath indexPathForItem:index inSection:0];
-    BOOL animated = options[@"animated"] ? [WXConvert BOOL:options[@"animated"]] : NO;
+    NSUInteger position = 0;
+    if ([virtalElementInfo isKindOfClass:[NSNumber class]]) {
+        position = [virtalElementInfo integerValue];
+    }
+    else
+    {
+        if (virtalElementInfo.length == 0) {
+            return;
+        }
+        position = [self _positionForVirtalElementInfo:virtalElementInfo];
+    }
+    NSIndexPath *toIndexPath = [NSIndexPath indexPathForItem:position inSection:0];
+    BOOL animated = options[@"animated"] ? [WXConvert BOOL:options[@"animated"]] : YES;
     [_collectionView scrollToItemAtIndexPath:toIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:animated];
 }
 
+- (void)scrollToElement:(NSString *)virtalElementInfo options:(NSDictionary *)options
+{
+    [self scrollTo:virtalElementInfo options:options];
+}
+
+- (void)queryElement:(NSString *)virtalElementInfo cssSelector:(NSString *)cssSelector callback:(WXModuleCallback)callback
+{
+    [self _queryElement:virtalElementInfo cssSelector:cssSelector callback:callback isAll:NO];
+}
+
+- (void)queryElementAll:(NSString *)virtalElementInfo cssSelector:(NSString *)cssSelector callback:(WXModuleCallback)callback
+{
+    [self _queryElement:virtalElementInfo cssSelector:cssSelector callback:callback isAll:YES];
+}
+
+- (NSString *)_refForVirtalElementInfo:(NSString *)virtalElementInfo
+{
+    NSArray *stringArray = [virtalElementInfo componentsSeparatedByString:@"@"];
+    if (stringArray.count == 2) {
+        return stringArray[0];
+    }
+    return nil;
+}
+
+- (NSUInteger )_positionForVirtalElementInfo:(NSString *)virtalElementInfo
+{
+    NSArray *stringArray = [virtalElementInfo componentsSeparatedByString:@"@"];
+    if (stringArray.count == 2) {
+        return [stringArray[1] integerValue];
+    }
+    return 0;
+}
+
+- (void)closest:(NSString *)virtalElementInfo cssSelector:(NSString *)cssSelector callback:(WXModuleCallback)callback
+{
+    if(callback)
+    {
+        WXPerformBlockOnComponentThread(^{
+            WXComponent *component = [self.weexInstance.componentManager componentForRef:[self _refForVirtalElementInfo:virtalElementInfo]];
+            if (component) {
+                callback([self _closestComponentForCSSSelector:cssSelector component:component]);
+            }
+        });
+    }
+}
+
+- (NSDictionary *)_closestComponentForCSSSelector:(NSString *)cssSelector component:(WXComponent *)component
+{
+    WXComponent *supercomponent = component.supercomponent;
+    if ([self _parseCssSelector:cssSelector component:supercomponent]) {
+        NSDictionary *info = @{@"attrs":supercomponent.attributes,@"type":supercomponent->_type,@"ref":supercomponent.ref};
+        return info;
+    }
+    else
+    {
+        if ([supercomponent isKindOfClass:[WXRecycleListComponent class]] ) {
+            return nil;
+        }
+        return [self _closestComponentForCSSSelector:cssSelector component:supercomponent];
+    }
+}
+
+- (void)_queryElement:(NSString *)virtalElementInfo cssSelector:(NSString *)cssSelector callback:(WXModuleCallback)callback isAll:(BOOL)isAll
+{
+    if(callback)
+    {
+        WXPerformBlockSyncOnComponentThread(^{
+            WXComponent *component = [self.weexInstance.componentManager componentForRef:[self _refForVirtalElementInfo:virtalElementInfo]];
+            if (component) {
+                NSMutableArray *infoArray = [NSMutableArray new];
+                [self _matchComponentForCSSSelector:cssSelector component:component infoArray:infoArray];
+                if (isAll) {
+                    callback(infoArray);
+                }
+                else
+                {
+                    if (infoArray.count != 0) {
+                        callback(infoArray[0]);
+                    }
+                }
+            }
+        });
+    }
+}
+
+- (void)_matchComponentForCSSSelector:(NSString *)cssSelector component:(WXComponent *)component infoArray:(NSMutableArray *)infoArray
+{
+    for (WXComponent *subcomponent in component.subcomponents) {
+        if ([self _parseCssSelector:cssSelector component:subcomponent]) {
+            NSDictionary *info = @{@"attrs":subcomponent.attributes,@"type":subcomponent->_type,@"ref":subcomponent.ref};
+            [infoArray addObject:info];
+        }
+        if (subcomponent.subcomponents.count != 0) {
+            [self _matchComponentForCSSSelector:cssSelector component:subcomponent infoArray:infoArray];
+        }
+    }
+}
+
+- (BOOL)_parseCssSelector:(NSString *)cssSelector component:(WXComponent *)component
+{
+    if (!cssSelector) {
+        return NO;
+    }
+    if ([cssSelector hasPrefix:@"["]&&[cssSelector hasSuffix:@"]"]) {
+        NSCharacterSet *unwantedChars = [NSCharacterSet characterSetWithCharactersInString:@"\"[]"];
+        NSString *requiredString = [[cssSelector componentsSeparatedByCharactersInSet:unwantedChars] componentsJoinedByString:@""];
+        NSArray *selectorArray = [requiredString componentsSeparatedByString:@"="];
+        if (selectorArray.count == 2) {
+            NSString *attribute = selectorArray[0];
+            NSString *value = selectorArray[1];
+            NSDictionary *componentAttrs = component.attributes;
+            NSString *valueString = [NSString stringWithFormat:@"%@",componentAttrs[attribute]];
+            if ([valueString isEqualToString:value]) {
+                return YES;
+            }
+        }
+    }
+    return NO;
+}
+
 #pragma mark - WXComponent Internal Methods
 
 - (void)_insertSubcomponent:(WXComponent *)subcomponent atIndex:(NSInteger)index
 {
    [super _insertSubcomponent:subcomponent atIndex:index];
-    
     if ([subcomponent isKindOfClass:[WXCellSlotComponent class]]) {
         WXCellSlotComponent *cell = (WXCellSlotComponent*)subcomponent;
         [self.weexInstance.componentManager _addUITask:^{
             [_templateManager addTemplate:cell];
         }];
-        
         //TODO: update collection view if adding template
     }
 }
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index 73f4d26d08..54a6fa0745 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -140,6 +140,8 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
     NSString *_repeatIndexIdentify;
     NSString *_repeatLabelIdentify;
     NSString *_virtualComponentId;// for recycleList subcomponent
+    NSMutableDictionary *_virtalElementInfo;
+
     BOOL _isRepeating;
     BOOL _isSkipUpdate;
     BOOL _dataBindOnce;
@@ -258,6 +260,10 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
 
 - (void)_didInserted;
 
+- (void)_attachSlotEvent:(NSDictionary *)data;
+
+- (void)_detachSlotEvent:(NSDictionary *)data;
+
 @end
 
 
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.mm b/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.mm
index 9b8a1a27ed..056ca4ed16 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.mm
@@ -354,7 +354,9 @@ - (void)removeStickyComponent:(WXComponent *)sticky
 {
     if([self.stickyArray containsObject:sticky]) {
         [self.stickyArray removeObject:sticky];
-        [self adjustSticky];
+		WXPerformBlockOnMainThread(^{
+			[self adjustSticky];
+		});
     }
 }
 
diff --git a/ios/sdk/WeexSDK/Sources/Controller/WXBaseViewController.m b/ios/sdk/WeexSDK/Sources/Controller/WXBaseViewController.m
index 5fa87b2e7d..9241cc9625 100644
--- a/ios/sdk/WeexSDK/Sources/Controller/WXBaseViewController.m
+++ b/ios/sdk/WeexSDK/Sources/Controller/WXBaseViewController.m
@@ -126,11 +126,10 @@ - (void)_renderWithURL:(NSURL *)sourceURL
     }
     
     [_instance destroyInstance];
+    _instance = [[WXSDKInstance alloc] init];
     if([WXPrerenderManager isTaskReady:[self.sourceURL absoluteString]]){
         _instance = [WXPrerenderManager instanceFromUrl:self.sourceURL.absoluteString];
     }
-
-    _instance = [[WXSDKInstance alloc] init];
     _instance.frame = CGRectMake(0.0f, 0.0f, self.view.bounds.size.width, self.view.bounds.size.height);
     _instance.pageObject = self;
     _instance.pageName = sourceURL.absoluteString;
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
index d877868eba..467a6b7ef5 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
@@ -602,6 +602,9 @@ - (void)_removeFromSupercomponent
         [self.weexInstance.componentManager removeFixedComponent:self];
         self->_isNeedJoinLayoutSystem = YES;
     }
+	if (_positionType == WXPositionTypeSticky) {
+		[self.ancestorScroller removeStickyComponent:self];
+	}
 }
 
 - (void)_moveToSupercomponent:(WXComponent *)newSupercomponent atIndex:(NSUInteger)index
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
index 6ed94414b3..a254b8ed43 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
@@ -152,7 +152,8 @@ - (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXMod
     _needLayout = NO;
     _isAnimationedSuccess = YES;
     WXPerformBlockOnComponentThread(^{
-        WXComponent *targetComponent = [self.weexInstance componentForRef:nodeRef];
+        NSArray *stringArray = [nodeRef componentsSeparatedByString:@"@"];
+        WXComponent *targetComponent = [self.weexInstance componentForRef:stringArray[0]];
         if (!targetComponent) {
             if (callback) {
                 NSDictionary *message = @{@"result":@"Fail",
@@ -167,7 +168,6 @@ - (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXMod
     });
 }
 
-
 - (NSArray<WXAnimationInfo *> *)animationInfoArrayFromArgs:(NSDictionary *)args target:(WXComponent *)target
 {
     UIView *view = target.view;
@@ -178,10 +178,12 @@ - (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXMod
     double delay = [args[@"delay"] doubleValue] / 1000;
     if (args[@"needLayout"]) {
         _needLayout = [WXConvert BOOL:args[@"needLayout"]];
-        _transition = [WXTransition new];
-        _transitionDic = [NSMutableDictionary new];
-        _transition.filterStyles = [NSMutableDictionary new];
-        _transition.oldFilterStyles = [NSMutableDictionary new];
+        if (_needLayout) {
+            _transition = [WXTransition new];
+            _transitionDic = [NSMutableDictionary new];
+            _transition.filterStyles = [NSMutableDictionary new];
+            _transition.oldFilterStyles = [NSMutableDictionary new];
+        }
     }
     CAMediaTimingFunction *timingFunction = [WXConvert CAMediaTimingFunction:args[@"timingFunction"]];
     NSDictionary *styles = args[@"styles"];


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services