feat:popover can dismiss all poped views

This commit is contained in:
pengfei.zhou 2019-11-29 09:35:20 +08:00
parent a79e288679
commit 35d377f9b9
8 changed files with 65 additions and 48 deletions

View File

@ -58,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onHidden;
- (DoricViewNode *)targetViewNode:(NSString *)viewId;
@end
NS_ASSUME_NONNULL_END

View File

@ -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];

View File

@ -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

View File

@ -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];

View File

@ -28,7 +28,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)setupRootView:(DoricStackView *)view;
- (void)render:(NSDictionary *)props;
@end
NS_ASSUME_NONNULL_END

View File

@ -27,9 +27,6 @@ - (void)setupRootView:(DoricStackView *)view {
self.view = view;
}
- (void)render:(NSDictionary *)props {
[self blend:props];
}
- (void)requestLayout {
[self.view setNeedsLayout];
}

View File

@ -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)
},
}
}

View File

@ -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()