diff --git a/iOS/Pod/Classes/DoricContext.h b/iOS/Pod/Classes/DoricContext.h index c21764f7..e51b8b7c 100644 --- a/iOS/Pod/Classes/DoricContext.h +++ b/iOS/Pod/Classes/DoricContext.h @@ -58,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)onHidden; +- (DoricViewNode *)targetViewNode:(NSString *)viewId; @end NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/DoricContext.m b/iOS/Pod/Classes/DoricContext.m index 011d86d9..b9bbbe75 100644 --- a/iOS/Pod/Classes/DoricContext.m +++ b/iOS/Pod/Classes/DoricContext.m @@ -36,7 +36,6 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source { _headNodes = [NSMutableSet new]; DoricRootNode *rootNode = [[DoricRootNode alloc] initWithContext:self]; _rootNode = rootNode; - [self.headNodes addObject:rootNode]; _script = script; _source = source; _initialParams = [@{@"width": @(0), @"height": @(0)} mutableCopy]; @@ -45,6 +44,19 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source { return self; } +- (DoricViewNode *)targetViewNode:(NSString *)viewId { + if ([self.rootNode.viewId isEqualToString:viewId]) { + return self.rootNode; + } else { + for (DoricViewNode *node in self.headNodes) { + if ([viewId isEqualToString:node.viewId]) { + return node; + } + } + return nil; + } +} + - (void)dealloc { [self callEntity:DORIC_ENTITY_DESTROY, nil]; [[DoricContextManager instance] destroyContext:self]; diff --git a/iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m b/iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m index 433e9bab..42b2864f 100644 --- a/iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m +++ b/iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m @@ -7,7 +7,6 @@ #import "Doric.h" @interface DoricPopoverPlugin () -@property(nonatomic, strong) DoricViewNode *popoverNode; @property(nonatomic, strong) UIView *fullScreenView; @end @@ -21,43 +20,51 @@ - (void)show:(NSDictionary *)params withPromise:(DoricPromise *)promise { it.height = superView.height; it.top = it.left = 0; [superView addSubview:it]; - UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissPopover)]; - [it addGestureRecognizer:gestureRecognizer]; }]; } [superView bringSubviewToFront:self.fullScreenView]; - if (self.popoverNode) { - [self dismissPopover]; - } self.fullScreenView.hidden = NO; NSString *viewId = params[@"id"]; NSString *type = params[@"type"]; - self.popoverNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) { - it.viewId = viewId; - [it initWithSuperNode:nil]; - it.view.layoutConfig = [DoricLayoutConfig new]; - [it blend:params[@"props"]]; - [self.fullScreenView addSubview:it.view]; - [self.doricContext.headNodes addObject:it]; - }]; + DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; + if (!viewNode) { + viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) { + it.viewId = viewId; + [it initWithSuperNode:nil]; + it.view.layoutConfig = [DoricLayoutConfig new]; + [self.fullScreenView addSubview:it.view]; + [self.doricContext.headNodes addObject:it]; + }]; + } + [viewNode blend:params[@"props"]]; [promise resolve:nil]; }); } - (void)dismiss:(NSDictionary *)params withPromise:(DoricPromise *)promise { + NSString *viewId = params[@"id"]; dispatch_async(dispatch_get_main_queue(), ^{ - [self dismissPopover]; + if (viewId) { + DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; + [self dismissViewNode:viewNode]; + } else { + [self dismissPopover]; + } [promise resolve:nil]; }); } +- (void)dismissViewNode:(DoricViewNode *)node { + [self.doricContext.headNodes removeObject:node]; + [node.view removeFromSuperview]; + if (self.doricContext.headNodes.count == 0) { + self.fullScreenView.hidden = YES; + } +} + - (void)dismissPopover { - [self.doricContext.headNodes removeObject:self.popoverNode]; - self.popoverNode.view.hidden = YES; - self.fullScreenView.hidden = YES; - [self.popoverNode.view.subviews forEach:^(__kindof UIView *obj) { - [obj removeFromSuperview]; - }]; - self.popoverNode = nil; + for (DoricViewNode *node in self.doricContext.headNodes) { + [self dismissViewNode:node]; + } } @end diff --git a/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m b/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m index ebe2b784..22f989e2 100644 --- a/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m +++ b/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m @@ -38,26 +38,17 @@ - (void)render:(NSDictionary *)argument { __strong typeof(_self) self = _self; NSString *viewId = argument[@"id"]; - if ([self.doricContext.rootNode.viewId isEqualToString:viewId]) { - [self.doricContext.rootNode render:argument[@"props"]]; + + if (self.doricContext.rootNode.viewId == nil) { + self.doricContext.rootNode.viewId = viewId; + [self.doricContext.rootNode blend:argument[@"props"]]; } else { - DoricViewNode *viewNode = [self headViewNodeByViewId:viewId]; + DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; [viewNode blend:argument[@"props"]]; } - }); } -- (DoricViewNode *)headViewNodeByViewId:(NSString *)viewId { - for (DoricViewNode *node in self.doricContext.headNodes) { - if ([viewId isEqualToString:node.viewId]) { - return node; - } - } - self.doricContext.rootNode.viewId = viewId; - return self.doricContext.rootNode; -} - - (id)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise { NSArray *viewIds = argument[@"viewIds"]; id args = argument[@"args"]; @@ -65,7 +56,7 @@ - (id)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise { DoricViewNode *viewNode = nil; for (NSString *viewId in viewIds) { if (!viewNode) { - viewNode = [self headViewNodeByViewId:viewId]; + viewNode = [self.doricContext targetViewNode:viewId]; } else { if ([viewNode isKindOfClass:[DoricSuperNode class]]) { viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId]; diff --git a/iOS/Pod/Classes/Shader/DoricRootNode.h b/iOS/Pod/Classes/Shader/DoricRootNode.h index 58bff00a..32abe898 100644 --- a/iOS/Pod/Classes/Shader/DoricRootNode.h +++ b/iOS/Pod/Classes/Shader/DoricRootNode.h @@ -28,7 +28,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)setupRootView:(DoricStackView *)view; -- (void)render:(NSDictionary *)props; @end NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Shader/DoricRootNode.m b/iOS/Pod/Classes/Shader/DoricRootNode.m index 7272a937..669c6bbb 100644 --- a/iOS/Pod/Classes/Shader/DoricRootNode.m +++ b/iOS/Pod/Classes/Shader/DoricRootNode.m @@ -27,9 +27,6 @@ - (void)setupRootView:(DoricStackView *)view { self.view = view; } -- (void)render:(NSDictionary *)props { - [self blend:props]; -} - (void)requestLayout { [self.view setNeedsLayout]; } diff --git a/js-framework/src/native/popover.ts b/js-framework/src/native/popover.ts index 802534ed..ff6834da 100644 --- a/js-framework/src/native/popover.ts +++ b/js-framework/src/native/popover.ts @@ -31,10 +31,14 @@ export function popover(context: BridgeContext) { return context.popover.show(view.toModel()) }, dismiss: (view: View | undefined = undefined) => { - if (panel && view) { - panel.removeHeadView(view) + if (panel) { + if (view) { + panel.removeHeadView(view) + } else { + panel.clearHeadViews() + } } - return context.popover.dismiss() + return context.popover.dismiss(view ? { id: view.viewId } : undefined) }, } } \ No newline at end of file diff --git a/js-framework/src/ui/panel.ts b/js-framework/src/ui/panel.ts index 2f6987db..e6ff2083 100644 --- a/js-framework/src/ui/panel.ts +++ b/js-framework/src/ui/panel.ts @@ -58,6 +58,10 @@ export abstract class Panel { } } + clearHeadViews() { + this.headviews.clear() + } + getRootView() { return this.__root__ } @@ -65,9 +69,6 @@ export abstract class Panel { getInitData() { return this.__data__ } - constructor() { - this.addHeadView(this.__root__) - } @NativeCall private __init__(frame: Frame, data: any) { @@ -137,6 +138,7 @@ export abstract class Panel { } private hookBeforeNativeCall() { + this.__root__.clean() for (let v of this.headviews.values()) { v.clean() } @@ -145,6 +147,10 @@ export abstract class Panel { private hookAfterNativeCall() { //Here insert a native call to ensure the promise is resolved done. nativeEmpty() + if (this.__root__.isDirty()) { + const model = this.__root__.toModel() + this.nativeRender(model) + } for (let v of this.headviews.values()) { if (v.isDirty()) { const model = v.toModel()