From 6bf61b37693328c493269185e7251f15f4dcf09c Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Thu, 13 Feb 2020 22:18:13 +0800 Subject: [PATCH] feat:iOS implement coordinator plugin --- .../pub/doric/plugin/CoordinatorPlugin.java | 4 + doric-demo/src/ImageDemo.ts | 33 +++-- doric-iOS/Pod/Classes/Doric.h | 3 +- doric-iOS/Pod/Classes/DoricRegistry.m | 2 + .../Pod/Classes/DoricScrollableProtocol.h | 10 ++ .../Pod/Classes/Plugin/DoricAnimatePlugin.h | 15 ++ .../Pod/Classes/Plugin/DoricAnimatePlugin.m | 15 ++ .../DoricCoordinatorPlugin.h} | 4 +- .../Classes/Plugin/DoricCoordinatorPlugin.m | 133 ++++++++++++++++++ .../Pod/Classes/Shader/DoricFlowLayoutNode.h | 6 +- .../Pod/Classes/Shader/DoricFlowLayoutNode.m | 4 +- doric-iOS/Pod/Classes/Shader/DoricListNode.h | 6 +- doric-iOS/Pod/Classes/Shader/DoricListNode.m | 4 +- .../Pod/Classes/Shader/DoricScrollerNode.h | 6 +- .../Pod/Classes/Shader/DoricScrollerNode.m | 5 +- 15 files changed, 226 insertions(+), 24 deletions(-) create mode 100644 doric-iOS/Pod/Classes/DoricScrollableProtocol.h rename doric-iOS/Pod/Classes/{DoricScrollViewDelegate.h => Plugin/DoricCoordinatorPlugin.h} (86%) create mode 100644 doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m diff --git a/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java b/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java index 8d1cc5c1..db71cee2 100644 --- a/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java +++ b/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java @@ -180,6 +180,10 @@ public class CoordinatorPlugin extends DoricJavaPlugin { viewNode.setWidth(value); } else if ("height".equals(name)) { viewNode.setHeight(value); + } else if ("x".equals(name)) { + viewNode.setX(value); + } else if ("y".equals(name)) { + viewNode.setY(value); } } diff --git a/doric-demo/src/ImageDemo.ts b/doric-demo/src/ImageDemo.ts index 8c228fdf..dd0de12f 100644 --- a/doric-demo/src/ImageDemo.ts +++ b/doric-demo/src/ImageDemo.ts @@ -1,4 +1,4 @@ -import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, Text, scroller, layoutConfig, image, IView, IVLayout, ScaleType, Image } from "doric"; +import { Group, Panel, coordinator, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, Text, scroller, layoutConfig, image, IView, IVLayout, ScaleType, Image } from "doric"; import { colors, label } from "./utils"; import { img_base64 } from "./image_base64"; const imageUrl = 'https://img.zcool.cn/community/01e75b5da933daa801209e1ffa4649.jpg@1280w_1l_2o_100sh.jpg' @@ -43,12 +43,15 @@ class ImageDemo extends Panel { label('WebP'), imageView = image({ imageUrl: "https://p.upyun.com/demo/webp/webp/jpg-0.webp", - loadCallback: (ret) => { - if (ret) { - imageView.width = ret.width - imageView.height = ret.height - } - } + layoutConfig: layoutConfig().just(), + width: 200, + height: 200, + // loadCallback: (ret) => { + // if (ret) { + // imageView.width = ret.width + // imageView.height = ret.height + // } + // } }), label('ScaleToFill'), image({ @@ -110,6 +113,20 @@ class ImageDemo extends Panel { { layoutConfig: layoutConfig().most(), } - ).in(rootView) + ).also(it => { + coordinator(context).verticalScrolling({ + scrollable: it, + scrollRange: { + start: 0, + end: 100, + }, + target: "NavBar", + changing: { + name: "backgroundColor", + start: Color.WHITE, + end: Color.RED, + } + }) + }).in(rootView) } } \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Doric.h b/doric-iOS/Pod/Classes/Doric.h index f7e6fc66..57b4bf3b 100644 --- a/doric-iOS/Pod/Classes/Doric.h +++ b/doric-iOS/Pod/Classes/Doric.h @@ -28,5 +28,4 @@ #import "DoricPromise.h" #import "DoricLibrary.h" #import "DoricNativePlugin.h" -#import "DoricMonitorProtocol.h" -#import "DoricScrollViewDelegate.h" \ No newline at end of file +#import "DoricMonitorProtocol.h" \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/DoricRegistry.m b/doric-iOS/Pod/Classes/DoricRegistry.m index e9d243b4..9c480f5f 100644 --- a/doric-iOS/Pod/Classes/DoricRegistry.m +++ b/doric-iOS/Pod/Classes/DoricRegistry.m @@ -49,6 +49,7 @@ #import "DoricNotificationPlugin.h" #import "DoricStatusBarPlugin.h" #import "DoricUtil.h" +#import "DoricCoordinatorPlugin.h" @interface DoricLibraries : NSObject @property(nonatomic, strong) NSMutableSet *libraries; @@ -130,6 +131,7 @@ - (void)innerRegister { [self registerNativePlugin:DoricAnimatePlugin.class withName:@"animate"]; [self registerNativePlugin:DoricNotificationPlugin.class withName:@"notification"]; [self registerNativePlugin:DoricStatusBarPlugin.class withName:@"statusbar"]; + [self registerNativePlugin:DoricCoordinatorPlugin.class withName:@"coordinator"]; [self registerViewNode:DoricStackNode.class withName:@"Stack"]; [self registerViewNode:DoricVLayoutNode.class withName:@"VLayout"]; diff --git a/doric-iOS/Pod/Classes/DoricScrollableProtocol.h b/doric-iOS/Pod/Classes/DoricScrollableProtocol.h new file mode 100644 index 00000000..2f281c3c --- /dev/null +++ b/doric-iOS/Pod/Classes/DoricScrollableProtocol.h @@ -0,0 +1,10 @@ +// +// Created by pengfei.zhou on 2020/2/13. +// + +#import +#import "DoricScrollableProtocol.h" + +@protocol DoricScrollableProtocol +@property(nonatomic, strong, nullable) void (^didScrollListener)(UIScrollView *__nonnull scrollView); +@end diff --git a/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.h b/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.h index 484284a9..722a5f96 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.h +++ b/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.h @@ -1,3 +1,18 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ // // Created by pengfei.zhou on 2019/11/29. // diff --git a/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m index 317e38a7..992706aa 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m @@ -1,3 +1,18 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ // // Created by pengfei.zhou on 2019/11/29. // diff --git a/doric-iOS/Pod/Classes/DoricScrollViewDelegate.h b/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.h similarity index 86% rename from doric-iOS/Pod/Classes/DoricScrollViewDelegate.h rename to doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.h index 6b44b126..20638d60 100644 --- a/doric-iOS/Pod/Classes/DoricScrollViewDelegate.h +++ b/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.h @@ -18,7 +18,7 @@ // #import +#import "DoricNativePlugin.h" -@protocol DoricScrollViewDelegate -- (void)scrollViewDidScroll:(UIScrollView *)scrollView; +@interface DoricCoordinatorPlugin : DoricNativePlugin @end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m new file mode 100644 index 00000000..ee2196c5 --- /dev/null +++ b/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m @@ -0,0 +1,133 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2020/2/13. +// + +#import "DoricCoordinatorPlugin.h" +#import "DoricSuperNode.h" +#import "DoricScrollableProtocol.h" +#import "DoricUtil.h" + +@implementation DoricCoordinatorPlugin +- (void)ready:(id)param withPromise:(DoricPromise *)promise { + dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + [promise resolve:nil]; + }); + }); +} + +- (void)verticalScrolling:(NSDictionary *)params withPromise:(DoricPromise *)promise { + dispatch_async(dispatch_get_main_queue(), ^{ + NSArray *scrollableIds = params[@"scrollable"]; + DoricViewNode *scrollNode = nil; + for (NSString *value in scrollableIds) { + if (!scrollNode) { + scrollNode = [self.doricContext targetViewNode:value]; + } else { + if ([scrollNode isKindOfClass:[DoricSuperNode class]]) { + scrollNode = [((DoricSuperNode *) scrollNode) subNodeWithViewId:value]; + } + } + } + if (!scrollNode) { + [promise reject:@"Cannot find scrollable view"]; + return; + } + NSDictionary *scrollRange = params[@"scrollRange"]; + CGFloat startAnchor = [scrollRange[@"start"] floatValue]; + CGFloat endAnchor = [scrollRange[@"end"] floatValue]; + id target = params[@"target"]; + BOOL isNavBar = false; + DoricViewNode *targetNode = nil; + if ([target isKindOfClass:[NSString class]] && [target isEqualToString:@"NavBar"]) { + isNavBar = true; + } else { + for (NSString *value in target) { + if (!targetNode) { + targetNode = [self.doricContext targetViewNode:value]; + } else { + if ([targetNode isKindOfClass:[DoricSuperNode class]]) { + targetNode = [((DoricSuperNode *) targetNode) subNodeWithViewId:value]; + } + } + } + if (!targetNode) { + [promise reject:@"Cannot find target view"]; + } + } + NSDictionary *changing = params[@"changing"]; + NSString *name = changing[@"name"]; + NSNumber *changingStart = changing[@"start"]; + NSNumber *changingEnd = changing[@"end"]; + if ([scrollNode conformsToProtocol:@protocol(DoricScrollableProtocol)]) { + ((id ) scrollNode).didScrollListener = ^(UIScrollView *scrollView) { + CGFloat scrollY = scrollView.contentOffset.y; + if (scrollY <= startAnchor) { + [self setValue:targetNode isNavBar:isNavBar name:name value:changingStart]; + } else if (scrollY >= endAnchor) { + [self setValue:targetNode isNavBar:isNavBar name:name value:changingEnd]; + } else { + CGFloat range = MAX(1, endAnchor - startAnchor); + CGFloat offset = scrollY - startAnchor; + CGFloat rate = offset / range; + id value; + if ([@"backgroundColor" isEqualToString:name]) { + UIColor *startColor = DoricColor(changingStart); + UIColor *endColor = DoricColor(changingEnd); + CGFloat startR, startG, startB, startA; + [startColor getRed:&startR green:&startG blue:&startB alpha:&startA]; + CGFloat endR, endG, endB, endA; + [endColor getRed:&endR green:&endG blue:&endB alpha:&endA]; + value = [UIColor colorWithRed:startR + (endR - startR) * rate + green:startG + (endG - startG) * rate + blue:startB + (endB - startB) * rate + alpha:startA + (endA - startA) * rate]; + } else { + value = @([changingStart floatValue] + ([changingEnd floatValue] - [changingStart floatValue]) * rate); + } + [self setValue:targetNode isNavBar:isNavBar name:name value:value]; + } + }; + } else { + [promise reject:@"Scroller type error"]; + } + }); +} + +- (void)setValue:(DoricViewNode *)viewNode isNavBar:(BOOL)isNavBar name:(NSString *)name value:(id)value { + if ([@"backgroundColor" isEqualToString:name]) { + if ([value isKindOfClass:[NSNumber class]]) { + value = DoricColor(value); + } + if (isNavBar) { + [self.doricContext.navBar doric_navBar_setBackgroundColor:value]; + } else { + viewNode.view.backgroundColor = value; + } + } else if ([@"width" isEqualToString:name]) { + viewNode.view.width = [value floatValue]; + } else if ([@"height" isEqualToString:name]) { + viewNode.view.height = [value floatValue]; + } else if ([@"x" isEqualToString:name]) { + viewNode.view.left = [value floatValue]; + } else if ([@"y" isEqualToString:name]) { + viewNode.view.top = [value floatValue]; + } +} + +@end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.h b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.h index 368a6516..109a0d2a 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.h +++ b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.h @@ -19,8 +19,8 @@ #import #import "DoricSuperNode.h" -#import "DoricScrollViewDelegate.h" +#import "DoricScrollableProtocol.h" -@interface DoricFlowLayoutNode : DoricSuperNode -@property(nonatomic, weak, nullable) id delegate; +@interface DoricFlowLayoutNode : DoricSuperNode +@property(nonatomic, strong, nullable) void (^didScrollListener)(UIScrollView *__nonnull scrollView); @end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m index 29db154f..8b0a36c0 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m @@ -370,6 +370,8 @@ - (NSInteger)doricFlowLayoutColumnCount { } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - [self.delegate scrollViewDidScroll:scrollView]; + if (self.didScrollListener) { + self.didScrollListener(scrollView); + } } @end diff --git a/doric-iOS/Pod/Classes/Shader/DoricListNode.h b/doric-iOS/Pod/Classes/Shader/DoricListNode.h index 68190d7b..ab98a4bb 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricListNode.h +++ b/doric-iOS/Pod/Classes/Shader/DoricListNode.h @@ -19,8 +19,8 @@ #import #import "DoricSuperNode.h" -#import "DoricScrollViewDelegate.h" +#import "DoricScrollableProtocol.h" -@interface DoricListNode : DoricSuperNode -@property(nonatomic, weak, nullable) id delegate; +@interface DoricListNode : DoricSuperNode +@property(nonatomic, strong, nullable) void (^didScrollListener)(UIScrollView *__nonnull scrollView); @end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Shader/DoricListNode.m b/doric-iOS/Pod/Classes/Shader/DoricListNode.m index 8376b9e3..1f19f31c 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricListNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricListNode.m @@ -250,6 +250,8 @@ - (DoricViewNode *)subNodeWithViewId:(NSString *)viewId { } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - [self.delegate scrollViewDidScroll:scrollView]; + if (self.didScrollListener) { + self.didScrollListener(scrollView); + } } @end diff --git a/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.h b/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.h index 18c46d91..cc2cd427 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.h +++ b/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.h @@ -21,12 +21,12 @@ // #import #import "DoricSuperNode.h" -#import "DoricScrollViewDelegate.h" +#import "DoricScrollableProtocol.h" @interface DoricScrollView : UIScrollView @property(nonatomic, strong) UIView *contentView; @end -@interface DoricScrollerNode : DoricSuperNode -@property(nonatomic, weak, nullable) id delegate; +@interface DoricScrollerNode : DoricSuperNode +@property(nonatomic, strong, nullable) void (^didScrollListener)(UIScrollView *__nonnull scrollView); @end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m b/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m index 474de0f4..67578225 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m @@ -124,7 +124,10 @@ - (DoricViewNode *)subNodeWithViewId:(NSString *)viewId { } return nil; } + - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - [self.delegate scrollViewDidScroll:scrollView]; + if (self.didScrollListener) { + self.didScrollListener(scrollView); + } } @end