diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.h b/iOS/Pod/Classes/Shader/DoricGroupNode.h index 202eb7c2..deccf40b 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.h +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.h @@ -25,6 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @interface DoricGroupNode : DoricSuperNode +@property(nonatomic, assign) BOOL reusable; @end NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.m b/iOS/Pod/Classes/Shader/DoricGroupNode.m index 5667f7ed..5a4aae7c 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.m +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.m @@ -34,6 +34,7 @@ - (instancetype)initWithContext:(DoricContext *)doricContext { if (self = [super initWithContext:doricContext]) { _childNodes = @[]; _childViewIds = @[]; + _reusable = NO; } return self; } @@ -73,43 +74,65 @@ - (void)configChildNodes { if ([viewId isEqualToString:oldNode.viewId]) { ///Same,skip } else { - ///Find in remain nodes - NSInteger position = -1; - for (NSUInteger start = idx + 1; start < childNodes.count; start++) { - DoricViewNode *node = childNodes[start]; - if ([viewId isEqualToString:node.viewId]) { - position = start; - break; + if (self.reusable) { + if ([oldNode.type isEqualToString:type]) { + ///Same type,can be reused + oldNode.viewId = viewId; + [oldNode blend:model[@"props"]]; + } else { + ///Replace this view + [childNodes removeObjectAtIndex:idx]; + [oldNode.view removeFromSuperview]; + DoricViewNode *viewNode = [DoricViewNode create:self.doricContext withType:type]; + if ([viewNode isKindOfClass:[DoricGroupNode class]]) { + ((DoricGroupNode *) viewNode).reusable = self.reusable; + } + viewNode.viewId = viewId; + [viewNode initWithSuperNode:self]; + [viewNode blend:model[@"props"]]; + [childNodes insertObject:viewNode atIndex:idx]; + [self.view insertSubview:viewNode.view atIndex:idx]; + } + } else { + ///Find in remain nodes + NSInteger position = -1; + for (NSUInteger start = idx + 1; start < childNodes.count; start++) { + DoricViewNode *node = childNodes[start]; + if ([viewId isEqualToString:node.viewId]) { + position = start; + break; + } + } + if (position >= 0) { + ///Found ,swap idx,position + DoricViewNode *reused = childNodes[(NSUInteger) position]; + [childNodes removeObjectAtIndex:(NSUInteger) position]; + [childNodes removeObjectAtIndex:idx]; + [childNodes insertObject:reused atIndex:idx]; + [childNodes insertObject:oldNode atIndex:(NSUInteger) position]; + + ///View swap index + [reused.view removeFromSuperview]; + [oldNode.view removeFromSuperview]; + [self.view insertSubview:reused.view atIndex:idx]; + [self.view insertSubview:oldNode.view atIndex:position]; + } else { + ///Not found,insert + DoricViewNode *viewNode = [DoricViewNode create:self.doricContext withType:type]; + viewNode.viewId = viewId; + [viewNode initWithSuperNode:self]; + [viewNode blend:model[@"props"]]; + [childNodes insertObject:viewNode atIndex:idx]; + [self.view insertSubview:viewNode.view atIndex:idx]; } } - if (position >= 0) { - ///Found ,swap idx,position - DoricViewNode *reused = childNodes[(NSUInteger) position]; - [childNodes removeObjectAtIndex:(NSUInteger) position]; - [childNodes removeObjectAtIndex:idx]; - [childNodes insertObject:reused atIndex:idx]; - [childNodes insertObject:oldNode atIndex:(NSUInteger) position]; - - ///View swap index - [reused.view removeFromSuperview]; - [oldNode.view removeFromSuperview]; - [self.view insertSubview:reused.view atIndex:idx]; - [self.view insertSubview:oldNode.view atIndex:position]; - } else { - ///Not found,insert - DoricViewNode *viewNode = [DoricViewNode create:self.doricContext withType:type]; - viewNode.viewId = viewId; - [viewNode initWithSuperNode:self]; - [viewNode blend:model[@"props"]]; - [childNodes insertObject:viewNode atIndex:idx]; - [self.view insertSubview:viewNode.view atIndex:idx]; - } } - - } else { /// Insert DoricViewNode *viewNode = [DoricViewNode create:self.doricContext withType:type]; + if ([viewNode isKindOfClass:[DoricGroupNode class]]) { + ((DoricGroupNode *) viewNode).reusable = self.reusable; + } viewNode.viewId = viewId; [viewNode initWithSuperNode:self]; [viewNode blend:model[@"props"]]; diff --git a/iOS/Pod/Classes/Shader/DoricViewNode.h b/iOS/Pod/Classes/Shader/DoricViewNode.h index 54cf533e..88b2c73e 100644 --- a/iOS/Pod/Classes/Shader/DoricViewNode.h +++ b/iOS/Pod/Classes/Shader/DoricViewNode.h @@ -30,12 +30,13 @@ NS_ASSUME_NONNULL_BEGIN @interface DoricViewNode : DoricContextHolder @property(nonatomic, strong) V view; - @property(nonatomic, weak) DoricSuperNode *superNode; @property(nonatomic) NSInteger index; @property(nonatomic, copy) NSString *viewId; +@property(nonatomic, copy) NSString *type; + @property(nonatomic, readonly) DoricLayoutConfig *layoutConfig; @property(nonatomic, readonly) NSArray *idList; diff --git a/iOS/Pod/Classes/Shader/DoricViewNode.m b/iOS/Pod/Classes/Shader/DoricViewNode.m index 9c3ded24..1ef9c6e2 100644 --- a/iOS/Pod/Classes/Shader/DoricViewNode.m +++ b/iOS/Pod/Classes/Shader/DoricViewNode.m @@ -211,7 +211,9 @@ - (DoricAsyncResult *)callJSResponse:(NSString *)funcId, ... { + (__kindof DoricViewNode *)create:(DoricContext *)context withType:(NSString *)type { DoricRegistry *registry = context.driver.registry; Class clz = [registry acquireViewNode:type]; - return [(DoricViewNode *) [clz alloc] initWithContext:context]; + DoricViewNode *viewNode = [(DoricViewNode *) [clz alloc] initWithContext:context]; + viewNode.type = type; + return viewNode; } - (void)requestLayout {