Merge branch 'iOS_master' into combine
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../../../js-framework/bundle
|
1
doric-iOS/Pod/Assets/bundle/.gitignore
vendored
Normal file
1
doric-iOS/Pod/Assets/bundle/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.js
|
@@ -25,4 +25,6 @@
|
||||
#import "DoricNavigatorDelegate.h"
|
||||
#import "DoricNavBarDelegate.h"
|
||||
#import "DoricViewController.h"
|
||||
#import "DoricPromise.h"
|
||||
#import "DoricPromise.h"
|
||||
#import "DoricLibrary.h"
|
||||
#import "DoricNativePlugin.h"
|
@@ -41,8 +41,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property(nonatomic, strong) NSMutableDictionary *initialParams;
|
||||
@property(nonatomic, strong) DoricRootNode *rootNode;
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, DoricViewNode *> *headNodes;
|
||||
@property(nonatomic, copy) NSString *extra;
|
||||
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source;
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source extra:(NSString *)extra;
|
||||
|
||||
- (DoricAsyncResult *)callEntity:(NSString *)method, ...;
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
@implementation DoricContext
|
||||
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source {
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source extra:(NSString *)extra {
|
||||
if (self = [super init]) {
|
||||
_driver = [DoricDriver instance];
|
||||
_pluginInstanceMap = [NSMutableDictionary new];
|
||||
@@ -39,6 +39,7 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source {
|
||||
_script = script;
|
||||
_source = source;
|
||||
_initialParams = [@{@"width": @(0), @"height": @(0)} mutableCopy];
|
||||
_extra = extra;
|
||||
[self callEntity:DORIC_ENTITY_CREATE, nil];
|
||||
}
|
||||
return self;
|
||||
@@ -78,7 +79,7 @@ - (void)initContextWithWidth:(CGFloat)width height:(CGFloat)height {
|
||||
it[@"width"] = @(width);
|
||||
it[@"height"] = @(height);
|
||||
}];
|
||||
[self callEntity:DORIC_ENTITY_INIT, self.initialParams, nil];
|
||||
[self callEntity:DORIC_ENTITY_INIT, self.initialParams, self.extra, nil];
|
||||
}
|
||||
|
||||
- (void)reload:(NSString *)script {
|
||||
@@ -86,6 +87,7 @@ - (void)reload:(NSString *)script {
|
||||
self.script = script;
|
||||
[self.driver createContext:self.contextId script:script source:self.source];
|
||||
[self callEntity:DORIC_ENTITY_INIT, self.initialParams, nil];
|
||||
[self onShow];
|
||||
}
|
||||
|
||||
- (void)onShow {
|
||||
|
@@ -26,7 +26,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DoricContextHolder : NSObject
|
||||
@property(nonatomic, strong) DoricContext *doricContext;
|
||||
@property(nonatomic, weak) DoricContext *doricContext;
|
||||
|
||||
- (instancetype)initWithContext:(DoricContext *)doricContext;
|
||||
|
||||
|
25
doric-iOS/Pod/Classes/DoricLibrary.h
Normal file
25
doric-iOS/Pod/Classes/DoricLibrary.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DoricRegistry.h"
|
||||
|
||||
@interface DoricLibrary : NSObject
|
||||
- (void)load:(DoricRegistry *)registry;
|
||||
@end
|
26
doric-iOS/Pod/Classes/DoricLibrary.m
Normal file
26
doric-iOS/Pod/Classes/DoricLibrary.m
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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/12/11.
|
||||
//
|
||||
|
||||
#import "DoricLibrary.h"
|
||||
|
||||
|
||||
@implementation DoricLibrary
|
||||
- (void)load:(DoricRegistry *)registry {
|
||||
}
|
||||
@end
|
@@ -25,5 +25,5 @@
|
||||
@interface DoricPanel : UIViewController
|
||||
@property(nonatomic, strong) DoricContext *doricContext;
|
||||
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias;
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias extra:(NSString *)extra;
|
||||
@end
|
@@ -22,8 +22,8 @@
|
||||
|
||||
@implementation DoricPanel
|
||||
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias {
|
||||
self.doricContext = [[[DoricContext alloc] initWithScript:script source:alias] also:^(DoricContext *it) {
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias extra:(NSString *)extra {
|
||||
self.doricContext = [[[DoricContext alloc] initWithScript:script source:alias extra:extra] also:^(DoricContext *it) {
|
||||
[it.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) {
|
||||
[self.view addSubview:it];
|
||||
}]];
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@class DoricLibrary;
|
||||
|
||||
@interface DoricRegistry : NSObject
|
||||
|
||||
@@ -38,6 +39,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)registerViewNode:(Class)nodeClass withName:(NSString *)name;
|
||||
|
||||
- (Class)acquireViewNode:(NSString *)name;
|
||||
|
||||
+ (void)register:(DoricLibrary *)library;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@@ -42,6 +42,35 @@
|
||||
#import "DoricFlowLayoutNode.h"
|
||||
#import "DoricPopoverPlugin.h"
|
||||
#import "DoricAnimatePlugin.h"
|
||||
#import "DoricNestedSliderNode.h"
|
||||
#import "DoricInputNode.h"
|
||||
#import "DoricLibrary.h"
|
||||
|
||||
|
||||
@interface DoricLibraries : NSObject
|
||||
@property(nonatomic, strong) NSMutableSet <DoricLibrary *> *libraries;
|
||||
|
||||
+ (instancetype)instance;
|
||||
@end
|
||||
|
||||
@implementation DoricLibraries
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_libraries = [NSMutableSet new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)instance {
|
||||
static DoricLibraries *_instance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_instance = [[DoricLibraries alloc] init];
|
||||
});
|
||||
return _instance;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface DoricRegistry ()
|
||||
|
||||
@@ -53,12 +82,19 @@ @interface DoricRegistry ()
|
||||
|
||||
@implementation DoricRegistry
|
||||
|
||||
+ (void)register:(DoricLibrary *)library {
|
||||
[DoricLibraries.instance.libraries addObject:library];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_bundles = [[NSMutableDictionary alloc] init];
|
||||
_plugins = [[NSMutableDictionary alloc] init];
|
||||
_nodes = [[NSMutableDictionary alloc] init];
|
||||
[self innerRegister];
|
||||
[DoricLibraries.instance.libraries enumerateObjectsUsingBlock:^(DoricLibrary *obj, BOOL *stop) {
|
||||
[obj load:self];
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -86,6 +122,8 @@ - (void)innerRegister {
|
||||
[self registerViewNode:DoricRefreshableNode.class withName:@"Refreshable"];
|
||||
[self registerViewNode:DoricFlowLayoutItemNode.class withName:@"FlowLayoutItem"];
|
||||
[self registerViewNode:DoricFlowLayoutNode.class withName:@"FlowLayout"];
|
||||
[self registerViewNode:DoricNestedSliderNode.class withName:@"NestedSlider"];
|
||||
[self registerViewNode:DoricInputNode.class withName:@"Input"];
|
||||
}
|
||||
|
||||
- (void)registerJSBundle:(NSString *)bundle withName:(NSString *)name {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* 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,
|
||||
* distributed under the License is distributed onO 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.
|
||||
@@ -22,5 +22,5 @@
|
||||
#import "DoricNavBarDelegate.h"
|
||||
|
||||
@interface DoricViewController : UIViewController <DoricNavigatorDelegate, DoricNavBarDelegate>
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias;
|
||||
@end
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias extra:(NSString *)extra;
|
||||
@end
|
||||
|
@@ -32,7 +32,7 @@ @interface DoricViewController ()
|
||||
@end
|
||||
|
||||
@implementation DoricViewController
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias {
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias extra:(NSString *)extra {
|
||||
if (self = [super init]) {
|
||||
self.edgesForExtendedLayout = UIRectEdgeNone;
|
||||
DoricAsyncResult <NSString *> *result = [DoricJSLoaderManager.instance request:scheme];
|
||||
@@ -46,7 +46,7 @@ - (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias {
|
||||
}];
|
||||
[self.view addSubview:panel.view];
|
||||
[self addChildViewController:panel];
|
||||
[panel config:result alias:alias];
|
||||
[panel config:result alias:alias extra:extra];
|
||||
panel.doricContext.navigator = self;
|
||||
panel.doricContext.navBar = self;
|
||||
self.doricPanel = panel;
|
||||
@@ -78,8 +78,8 @@ - (void)viewWillLayoutSubviews {
|
||||
self.doricPanel.view.height = self.view.height;
|
||||
}
|
||||
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated {
|
||||
DoricViewController *viewController = [[DoricViewController alloc] initWithScheme:scheme alias:alias];
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated extra:(NSString *)extra {
|
||||
DoricViewController *viewController = [[DoricViewController alloc] initWithScheme:scheme alias:alias extra:extra];
|
||||
[self.navigationController pushViewController:viewController animated:animated];
|
||||
}
|
||||
|
||||
|
@@ -55,12 +55,20 @@ - (instancetype)init {
|
||||
|
||||
- (void)initJSExecutor {
|
||||
__weak typeof(self) _self = self;
|
||||
|
||||
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
||||
[self.jsExecutor injectGlobalJSObject:INJECT_ENVIRONMENT obj:@{
|
||||
@"platform": @"iOS",
|
||||
@"platformVersion": [[UIDevice currentDevice] systemVersion],
|
||||
@"appName": infoDictionary[@"CFBundleName"],
|
||||
@"appVersion": infoDictionary[@"CFBundleShortVersionString"],
|
||||
@"screenWidth": @([[UIScreen mainScreen] bounds].size.width),
|
||||
@"screenHeight": @([[UIScreen mainScreen] bounds].size.height),
|
||||
}];
|
||||
[self.jsExecutor injectGlobalJSObject:INJECT_LOG obj:^(NSString *type, NSString *message) {
|
||||
DoricLog(@"JS:%@", message);
|
||||
}];
|
||||
[self.jsExecutor injectGlobalJSObject:INJECT_EMPTY obj:^() {
|
||||
|
||||
|
||||
}];
|
||||
[self.jsExecutor injectGlobalJSObject:INJECT_REQUIRE obj:^(NSString *name) {
|
||||
__strong typeof(_self) self = _self;
|
||||
|
@@ -50,6 +50,7 @@ - (instancetype)init {
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - SRWebSocketDelegate
|
||||
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
|
||||
DoricLog(@"debugger webSocketDidOpen");
|
||||
DC_UNLOCK(self.semaphore);
|
||||
@@ -93,6 +94,8 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
|
||||
result = ((Block4)tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3]);
|
||||
} else if (argsArr.count == 5) {
|
||||
result = ((Block5)tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3], argsArr[4]);
|
||||
}else {
|
||||
DoricLog(@"error:args to more than 5. args:%@",argsArr);
|
||||
}
|
||||
|
||||
} else if ([cmd isEqualToString:@"invokeMethod"]) {
|
||||
@@ -115,6 +118,7 @@ - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reas
|
||||
DoricLog(@"debugger webSocketdidCloseWithCode");
|
||||
}
|
||||
|
||||
#pragma mark - DoricJSExecutorProtocol
|
||||
- (NSString *)loadJSScript:(NSString *)script source:(NSString *)source {
|
||||
|
||||
return nil;
|
||||
@@ -141,10 +145,7 @@ - (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(
|
||||
|
||||
NSMutableArray *argsMArr = [NSMutableArray new];
|
||||
for (id arg in args) {
|
||||
NSDictionary *dic = @{
|
||||
@"type": @(DoricargTypeWithArg(arg)),
|
||||
@"value": arg
|
||||
};
|
||||
NSDictionary *dic = [self dicForArg:arg];
|
||||
[argsMArr addObject:dic];
|
||||
}
|
||||
|
||||
@@ -168,6 +169,19 @@ - (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(
|
||||
return self.temp;
|
||||
}
|
||||
|
||||
- (NSDictionary *)dicForArg:(id)arg {
|
||||
DoricJSRemoteArgType type = DoricargTypeWithArg(arg);
|
||||
if (type == DoricJSRemoteArgTypeObject || type == DoricJSRemoteArgTypeArray) {
|
||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:(NSDictionary *)arg];
|
||||
arg = jsonStr;
|
||||
}
|
||||
NSDictionary *dic = @{
|
||||
@"type": @(type),
|
||||
@"value": arg
|
||||
};
|
||||
return dic;
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
[self.srWebSocket close];
|
||||
}
|
||||
|
@@ -73,11 +73,15 @@ - (id)findClass:(Class)clz target:(id)target context:(DoricContext *)context met
|
||||
dispatch_block_t block = ^() {
|
||||
__strong __typeof__(_self) self = _self;
|
||||
@try {
|
||||
NSMutableArray *tempArray = [NSMutableArray new];
|
||||
for (NSUInteger idx = 2; idx < methodSignature.numberOfArguments; idx++) {
|
||||
if (idx - 2 > [array count]) {
|
||||
break;
|
||||
}
|
||||
id args = [self createParamWithMethodName:array[idx - 2] context:context callbackId:callbackId argument:argument];
|
||||
if (args) {
|
||||
[tempArray addObject:args];
|
||||
}
|
||||
[invocation setArgument:&args atIndex:idx];
|
||||
}
|
||||
[invocation invoke];
|
||||
|
@@ -18,7 +18,7 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol DoricNavBarDelegate <NSObject>
|
||||
- (BOOL)doric_navBar_isHidden;
|
||||
@@ -28,4 +28,4 @@
|
||||
- (void)doric_navBar_setTitle:(NSString *)title;
|
||||
|
||||
- (void)doric_navBar_setBackgroundColor:(UIColor *)color;
|
||||
@end
|
||||
@end
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol DoricNavigatorDelegate <NSObject>
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated;
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated extra:(NSString *)extra;
|
||||
|
||||
- (void)doric_navigator_pop:(BOOL)animated;
|
||||
@end
|
||||
@end
|
||||
|
@@ -20,9 +20,9 @@
|
||||
// Created by pengfei.zhou on 2019/7/29.
|
||||
//
|
||||
|
||||
#import <Doric/Doric.h>
|
||||
#import "DoricModalPlugin.h"
|
||||
#import "DoricUtil.h"
|
||||
#import "DoricExtensions.h"
|
||||
|
||||
@implementation DoricModalPlugin
|
||||
|
||||
|
@@ -24,10 +24,19 @@ @implementation DoricNavigatorPlugin
|
||||
- (void)push:(NSDictionary *)params {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
BOOL animated = YES;
|
||||
if (params[@"animated"]) {
|
||||
animated = [params[@"animated"] boolValue];
|
||||
NSString *scheme = params[@"scheme"];
|
||||
NSString *alias = scheme;
|
||||
NSDictionary *config = params[@"config"];
|
||||
if (config) {
|
||||
if (config[@"animated"]) {
|
||||
animated = [config[@"animated"] boolValue];
|
||||
}
|
||||
|
||||
if (config[@"alias"]) {
|
||||
alias = config[@"alias"];
|
||||
}
|
||||
}
|
||||
[self.doricContext.navigator doric_navigator_push:params[@"scheme"] alias:params[@"alias"] animated:animated];
|
||||
[self.doricContext.navigator doric_navigator_push:scheme alias:alias animated:animated extra:config[@"extra"]];
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,8 @@
|
||||
@protocol DoricFlowLayoutDelegate
|
||||
- (CGFloat)doricFlowLayoutItemHeightAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (CGFloat)doricFlowLayoutItemWidthAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (CGFloat)doricFlowLayoutColumnSpace;
|
||||
|
||||
- (CGFloat)doricFlowLayoutRowSpace;
|
||||
@@ -93,15 +95,23 @@ - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSInde
|
||||
}
|
||||
}
|
||||
|
||||
CGFloat width = (self.collectionView.width - self.columnSpace * (self.columnCount - 1)) / self.columnCount;
|
||||
CGFloat width = [self.delegate doricFlowLayoutItemWidthAtIndexPath:indexPath];
|
||||
CGFloat height = [self.delegate doricFlowLayoutItemHeightAtIndexPath:indexPath];
|
||||
CGFloat x = (width + self.columnSpace) * [minYOfColumn integerValue];
|
||||
CGFloat y = [self.columnHeightInfo[minYOfColumn] floatValue];
|
||||
if (y > 0) {
|
||||
y += self.rowSpace;
|
||||
}
|
||||
self.columnHeightInfo[minYOfColumn] = @(y + height);
|
||||
|
||||
if (width == self.collectionView.width) {
|
||||
CGFloat maxY = 0;
|
||||
for (NSNumber *column in self.columnHeightInfo.allValues) {
|
||||
maxY = MAX(maxY, [column floatValue]);
|
||||
}
|
||||
y = maxY + self.rowSpace;
|
||||
} else {
|
||||
self.columnHeightInfo[minYOfColumn] = @(y + height);
|
||||
}
|
||||
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
|
||||
attrs.frame = CGRectMake(x, y, width, height);
|
||||
return attrs;
|
||||
@@ -156,6 +166,11 @@ @interface DoricFlowLayoutNode () <UICollectionViewDataSource, UICollectionViewD
|
||||
@property(nonatomic, assign) NSUInteger columnCount;
|
||||
@property(nonatomic, assign) CGFloat columnSpace;
|
||||
@property(nonatomic, assign) CGFloat rowSpace;
|
||||
@property(nonatomic, copy) NSString *renderItemFuncId;
|
||||
|
||||
@property(nonatomic, copy) NSString *onLoadMoreFuncId;
|
||||
@property(nonatomic, copy) NSString *loadMoreViewId;
|
||||
@property(nonatomic, assign) BOOL loadMore;
|
||||
@end
|
||||
|
||||
@implementation DoricFlowLayoutNode
|
||||
@@ -180,6 +195,7 @@ - (UICollectionView *)build {
|
||||
it.delegate = self;
|
||||
it.dataSource = self;
|
||||
[it registerClass:[DoricFlowLayoutViewCell class] forCellWithReuseIdentifier:@"doricCell"];
|
||||
[it registerClass:[DoricFlowLayoutViewCell class] forCellWithReuseIdentifier:@"doricLoadMoreCell"];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -198,17 +214,31 @@ - (void)blendView:(UICollectionView *)view forPropName:(NSString *)name propValu
|
||||
self.itemCount = [prop unsignedIntegerValue];
|
||||
[self.view reloadData];
|
||||
} else if ([@"renderItem" isEqualToString:name]) {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
if ([self.renderItemFuncId isEqualToString:prop]) {
|
||||
} else {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
self.renderItemFuncId = prop;
|
||||
}
|
||||
|
||||
} else if ([@"batchCount" isEqualToString:name]) {
|
||||
self.batchCount = [prop unsignedIntegerValue];
|
||||
} else if ([@"onLoadMore" isEqualToString:name]) {
|
||||
self.onLoadMoreFuncId = prop;
|
||||
} else if ([@"loadMoreView" isEqualToString:name]) {
|
||||
self.loadMoreViewId = prop;
|
||||
} else if ([@"loadMore" isEqualToString:name]) {
|
||||
self.loadMore = [prop boolValue];
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)itemModelAt:(NSUInteger)position {
|
||||
if (position >= self.itemCount) {
|
||||
return [self subModelOf:self.loadMoreViewId];
|
||||
}
|
||||
NSString *viewId = self.itemViewIds[@(position)];
|
||||
if (viewId && viewId.length > 0) {
|
||||
return [self subModelOf:viewId];
|
||||
@@ -243,24 +273,26 @@ - (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
|
||||
}
|
||||
|
||||
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadItemsAtIndexPaths:@[indexPath]];
|
||||
}];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
}];
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadItemsAtIndexPaths:@[indexPath]];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)callItem:(NSUInteger)position size:(CGSize)size {
|
||||
@@ -273,13 +305,14 @@ - (void)callItem:(NSUInteger)position size:(CGSize)size {
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
return self.itemCount;
|
||||
return self.itemCount + (self.loadMore ? 1 : 0);
|
||||
}
|
||||
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSUInteger position = (NSUInteger) indexPath.row;
|
||||
NSDictionary *model = [self itemModelAt:position];
|
||||
NSDictionary *props = model[@"props"];
|
||||
|
||||
DoricFlowLayoutViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"doricCell" forIndexPath:indexPath];
|
||||
if (!cell.viewNode) {
|
||||
DoricFlowLayoutItemNode *itemNode = [[DoricFlowLayoutItemNode alloc] initWithContext:self.doricContext];
|
||||
@@ -287,11 +320,17 @@ - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collection
|
||||
cell.viewNode = itemNode;
|
||||
[cell.contentView addSubview:itemNode.view];
|
||||
}
|
||||
|
||||
DoricFlowLayoutItemNode *node = cell.viewNode;
|
||||
node.viewId = model[@"id"];
|
||||
[node blend:props];
|
||||
CGFloat width = (collectionView.width - (self.columnCount - 1) * self.columnSpace) / self.columnCount;
|
||||
CGSize size = [node.view measureSize:CGSizeMake(width, collectionView.height)];
|
||||
if (position > 0 && position >= self.itemCount && self.onLoadMoreFuncId) {
|
||||
size = CGSizeMake(collectionView.width, size.height);
|
||||
[self callJSResponse:self.onLoadMoreFuncId, nil];
|
||||
}
|
||||
|
||||
[node.view layoutSelf:size];
|
||||
[self callItem:position size:size];
|
||||
return cell;
|
||||
@@ -307,6 +346,17 @@ - (CGFloat)doricFlowLayoutItemHeightAtIndexPath:(NSIndexPath *)indexPath {
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)doricFlowLayoutItemWidthAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSUInteger position = (NSUInteger) indexPath.row;
|
||||
NSValue *value = self.itemSizeInfo[@(position)];
|
||||
if (value) {
|
||||
return [value CGSizeValue].width;
|
||||
} else {
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (CGFloat)doricFlowLayoutColumnSpace {
|
||||
return self.columnSpace;
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@
|
||||
// Created by pengfei.zhou on 2019/7/30.
|
||||
//
|
||||
|
||||
#import <Doric/DoricExtensions.h>
|
||||
#import "DoricGroupNode.h"
|
||||
|
||||
@interface DoricGroupNode ()
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
@interface DoricImageNode ()
|
||||
@property(nonatomic, copy) NSString *loadCallbackId;
|
||||
@property(nonatomic, assign) BOOL isBlur;
|
||||
@end
|
||||
|
||||
@implementation DoricImageNode
|
||||
@@ -36,6 +37,15 @@ - (UIImageView *)build {
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)blend:(NSDictionary *)props {
|
||||
NSInteger value = [props[@"isBlur"] intValue];
|
||||
if(value == 1) {
|
||||
self.isBlur = YES;
|
||||
}
|
||||
|
||||
[super blend:props];
|
||||
}
|
||||
|
||||
- (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||
if ([@"imageUrl" isEqualToString:name]) {
|
||||
__weak typeof(self) _self = self;
|
||||
@@ -53,6 +63,13 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id
|
||||
}
|
||||
[self requestLayout];
|
||||
}
|
||||
|
||||
if(self.isBlur) {
|
||||
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
|
||||
UIVisualEffectView *effectView = [[UIVisualEffectView alloc]initWithEffect:blurEffect];
|
||||
effectView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
|
||||
[view addSubview:effectView];
|
||||
}
|
||||
}];
|
||||
} else if ([@"scaleType" isEqualToString:name]) {
|
||||
switch ([prop integerValue]) {
|
||||
|
31
doric-iOS/Pod/Classes/Shader/DoricInputNode.h
Normal file
31
doric-iOS/Pod/Classes/Shader/DoricInputNode.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
//
|
||||
// DoricInputNode.h
|
||||
// Doric
|
||||
//
|
||||
// Created by 姜腾 on 2019/12/11.
|
||||
//
|
||||
|
||||
#import "DoricViewNode.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DoricInputNode : DoricViewNode<UITextView *>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
173
doric-iOS/Pod/Classes/Shader/DoricInputNode.m
Normal file
173
doric-iOS/Pod/Classes/Shader/DoricInputNode.m
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
//
|
||||
// DoricInputNode.m
|
||||
// Doric
|
||||
//
|
||||
// Created by 姜腾 on 2019/12/11.
|
||||
//
|
||||
|
||||
#import "DoricInputNode.h"
|
||||
#import "DoricUtil.h"
|
||||
#import "DoricPromise.h"
|
||||
|
||||
typedef void (^onTextChangeBlock)(NSString *text,DoricInputNode *node);
|
||||
typedef void (^onFocusChangeBlock)(BOOL focused,DoricInputNode *node);
|
||||
|
||||
@interface DoricInputNode()<UITextViewDelegate>
|
||||
@property(nonatomic, copy) onTextChangeBlock onTextChange;
|
||||
@property(nonatomic, copy) onFocusChangeBlock onFocusShange;
|
||||
@property(nonatomic, strong) UILabel *placeholderLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DoricInputNode
|
||||
- (UITextView *)build {
|
||||
UITextView *v = [[UITextView alloc] init];
|
||||
v.delegate = self;
|
||||
return v;
|
||||
}
|
||||
|
||||
- (void)blendView:(UITextView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||
if ([name isEqualToString:@"text"]) {
|
||||
view.text = prop;
|
||||
} else if ([name isEqualToString:@"textSize"]) {
|
||||
view.font = [UIFont systemFontOfSize:[(NSNumber *) prop floatValue]];
|
||||
} else if ([name isEqualToString:@"textColor"]) {
|
||||
view.textColor = DoricColor(prop);
|
||||
} else if ([name isEqualToString:@"textAlignment"]) {
|
||||
DoricGravity gravity = (DoricGravity) [(NSNumber *) prop integerValue];
|
||||
NSTextAlignment alignment = NSTextAlignmentCenter;
|
||||
if ((gravity & LEFT) == LEFT) {
|
||||
alignment = NSTextAlignmentLeft;
|
||||
} else if ((gravity & RIGHT) == RIGHT) {
|
||||
alignment = NSTextAlignmentRight;
|
||||
}
|
||||
view.textAlignment = alignment;
|
||||
} else if ([name isEqualToString:@"multiline"]) {
|
||||
BOOL mutilin = [(NSNumber *) prop boolValue];
|
||||
if (!mutilin) {
|
||||
view.textContainer.maximumNumberOfLines = 1;
|
||||
}else {
|
||||
view.textContainer.maximumNumberOfLines = 0;
|
||||
}
|
||||
} else if ([name isEqualToString:@"hintText"]) {
|
||||
self.placeholderLabel.text = (NSString *)prop;
|
||||
} else if ([name isEqualToString:@"hintTextColor"]) {
|
||||
self.placeholderLabel.textColor = DoricColor(prop);
|
||||
} else if ([name isEqualToString:@"onTextChange"]) {
|
||||
if ([prop isKindOfClass:[NSString class]]) {
|
||||
self.onTextChange = ^(NSString *text, DoricInputNode *node) {
|
||||
[node callJSResponse:prop,text,nil];
|
||||
};
|
||||
}else {
|
||||
self.onTextChange = nil;
|
||||
}
|
||||
} else if ([name isEqualToString:@"onFocusChange"]) {
|
||||
if ([prop isKindOfClass:[NSString class]]) {
|
||||
self.onFocusShange = ^(BOOL focused, DoricInputNode *node) {
|
||||
[node callJSResponse:prop,@(focused),nil];
|
||||
};
|
||||
}else {
|
||||
self.onFocusShange = nil;
|
||||
}
|
||||
|
||||
} else{
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)blend:(NSDictionary *)props {
|
||||
[super blend:props];
|
||||
[self updatePlaceholderLabel];
|
||||
[self.view.superview setNeedsLayout];
|
||||
}
|
||||
|
||||
#pragma mark - Doric-JS api
|
||||
- (NSString *)getText {
|
||||
return self.view.text;
|
||||
}
|
||||
|
||||
- (void)setSelection:(NSDictionary *)params withPromise:(DoricPromise *)promise {
|
||||
NSString *start = params[@"start"];
|
||||
NSString *end = params[@"end"];
|
||||
|
||||
if (([start isKindOfClass:[NSString class]] || [start isKindOfClass:[NSNumber class]]) &&
|
||||
([start isKindOfClass:[NSString class]] || [start isKindOfClass:[NSNumber class]])) {
|
||||
self.view.selectedRange = NSMakeRange(start.intValue, end.intValue - start.intValue);
|
||||
}
|
||||
|
||||
[promise resolve:nil];
|
||||
}
|
||||
|
||||
- (void)requestFocus {
|
||||
[self.view becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (void)releaseFocus {
|
||||
[self.view resignFirstResponder];
|
||||
}
|
||||
|
||||
#pragma mark - UITextViewDelegate
|
||||
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
|
||||
if (self.onFocusShange) {
|
||||
self.onFocusShange(YES, self);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
|
||||
if (self.onFocusShange) {
|
||||
self.onFocusShange(NO, self);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)textViewDidChange:(UITextView *)textView {
|
||||
if (self.onTextChange) {
|
||||
self.onTextChange(textView.text, self);
|
||||
}
|
||||
[self updatePlaceholderLabel];
|
||||
}
|
||||
|
||||
#pragma mark - placeholderLabel
|
||||
- (UILabel *)placeholderLabel {
|
||||
if (!_placeholderLabel) {
|
||||
_placeholderLabel = [[UILabel alloc] init];
|
||||
_placeholderLabel.numberOfLines = 0;
|
||||
_placeholderLabel.userInteractionEnabled = NO;
|
||||
}
|
||||
return _placeholderLabel;
|
||||
}
|
||||
|
||||
- (void)updatePlaceholderLabel {
|
||||
if (self.view.text.length) {
|
||||
[self.placeholderLabel removeFromSuperview];
|
||||
return;
|
||||
} else {
|
||||
[self.view insertSubview:self.placeholderLabel atIndex:0];
|
||||
}
|
||||
|
||||
self.placeholderLabel.textAlignment = self.view.textAlignment;
|
||||
CGFloat lineFragmentPadding = self.view.textContainer.lineFragmentPadding;
|
||||
UIEdgeInsets textContainerInset = self.view.textContainerInset;
|
||||
|
||||
CGFloat x = lineFragmentPadding + textContainerInset.left;
|
||||
CGFloat y = textContainerInset.top;
|
||||
CGFloat width = CGRectGetWidth(self.view.bounds) - x - lineFragmentPadding - textContainerInset.right;
|
||||
CGFloat height = [self.placeholderLabel sizeThatFits:CGSizeMake(width, 0)].height;
|
||||
self.placeholderLabel.frame = CGRectMake(x, y, width, height);
|
||||
}
|
||||
@end
|
@@ -18,8 +18,11 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef UIEdgeInsets DoricMargin;
|
||||
typedef UIEdgeInsets DoricPadding;
|
||||
|
||||
DoricMargin DoricMarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom);
|
||||
|
||||
@@ -82,6 +85,10 @@ typedef NS_ENUM(NSInteger, DoricGravity) {
|
||||
@property(nonatomic, strong) DoricLayoutConfig *layoutConfig;
|
||||
@end
|
||||
|
||||
@interface UIView (DoricPadding)
|
||||
@property(nonatomic, assign) DoricPadding padding;
|
||||
@end
|
||||
|
||||
@interface UIView (DoricTag)
|
||||
@property(nonatomic, copy) NSString *tagString;
|
||||
|
||||
@@ -96,4 +103,4 @@ typedef NS_ENUM(NSInteger, DoricGravity) {
|
||||
- (void)doricLayoutSubviews;
|
||||
|
||||
- (BOOL)requestFromSubview:(UIView *)subview;
|
||||
@end
|
||||
@end
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
#import "DoricLayouts.h"
|
||||
#import <objc/runtime.h>
|
||||
#import <Doric/DoricLayouts.h>
|
||||
#import "UIView+Doric.h"
|
||||
|
||||
static const void *kLayoutConfig = &kLayoutConfig;
|
||||
@@ -37,6 +36,24 @@ - (DoricLayoutConfig *)layoutConfig {
|
||||
|
||||
@end
|
||||
|
||||
static const void *kLayoutPadding = &kLayoutPadding;
|
||||
|
||||
@implementation UIView (DoricPadding)
|
||||
@dynamic padding;
|
||||
|
||||
- (void)setPadding:(DoricPadding)padding {
|
||||
objc_setAssociatedObject(self, kLayoutPadding, [NSValue value:&padding withObjCType:@encode(DoricPadding)], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (DoricPadding)padding {
|
||||
DoricPadding value;
|
||||
value.left = value.right = value.top = value.bottom = 0;
|
||||
[objc_getAssociatedObject(self, kLayoutPadding) getValue:&value];
|
||||
return value;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static const void *kTagString = &kTagString;
|
||||
|
||||
@implementation UIView (DoricTag)
|
||||
@@ -79,13 +96,15 @@ - (CGSize)measureSize:(CGSize)targetSize {
|
||||
|| config.heightSpec == DoricLayoutWrapContent) {
|
||||
height = targetSize.height - config.margin.top - config.margin.bottom;
|
||||
}
|
||||
|
||||
CGSize contentSize = [self sizeThatFits:CGSizeMake(width, height)];
|
||||
DoricPadding padding = self.padding;
|
||||
CGSize contentSize = [self sizeThatFits:CGSizeMake(
|
||||
width - padding.left - padding.right,
|
||||
height - padding.top - padding.bottom)];
|
||||
if (config.widthSpec == DoricLayoutWrapContent) {
|
||||
width = contentSize.width;
|
||||
width = contentSize.width + padding.left + padding.right;
|
||||
}
|
||||
if (config.heightSpec == DoricLayoutWrapContent) {
|
||||
height = contentSize.height;
|
||||
height = contentSize.height + padding.left + padding.top + padding.bottom;
|
||||
}
|
||||
return CGSizeMake(width, height);
|
||||
}
|
||||
@@ -208,6 +227,8 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
self.width = targetSize.width;
|
||||
self.height = targetSize.height;
|
||||
DoricPadding padding = self.padding;
|
||||
|
||||
for (UIView *child in self.subviews) {
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
@@ -219,33 +240,35 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
if (!childConfig) {
|
||||
childConfig = [DoricLayoutConfig new];
|
||||
}
|
||||
CGSize size = [child measureSize:CGSizeMake(targetSize.width, targetSize.height)];
|
||||
CGSize size = [child measureSize:CGSizeMake(
|
||||
targetSize.width - padding.left - padding.right,
|
||||
targetSize.height - padding.top - padding.bottom)];
|
||||
[child layoutSelf:size];
|
||||
DoricGravity gravity = childConfig.alignment;
|
||||
if ((gravity & LEFT) == LEFT) {
|
||||
child.left = 0;
|
||||
child.left = padding.left;
|
||||
} else if ((gravity & RIGHT) == RIGHT) {
|
||||
child.right = targetSize.width;
|
||||
child.right = targetSize.width - padding.right;
|
||||
} else if ((gravity & CENTER_X) == CENTER_X) {
|
||||
child.centerX = targetSize.width / 2;
|
||||
} else {
|
||||
if (childConfig.margin.left) {
|
||||
child.left = childConfig.margin.left;
|
||||
child.left = childConfig.margin.left + padding.left;
|
||||
} else if (childConfig.margin.right) {
|
||||
child.right = targetSize.width - childConfig.margin.right;
|
||||
child.right = targetSize.width - childConfig.margin.right - padding.right;
|
||||
}
|
||||
}
|
||||
if ((gravity & TOP) == TOP) {
|
||||
child.top = 0;
|
||||
child.top = padding.top;
|
||||
} else if ((gravity & BOTTOM) == BOTTOM) {
|
||||
child.bottom = targetSize.height;
|
||||
child.bottom = targetSize.height - padding.bottom;
|
||||
} else if ((gravity & CENTER_Y) == CENTER_Y) {
|
||||
child.centerY = targetSize.height / 2;
|
||||
} else {
|
||||
if (childConfig.margin.top) {
|
||||
child.top = childConfig.margin.top;
|
||||
child.top = childConfig.margin.top + padding.top;
|
||||
} else if (childConfig.margin.bottom) {
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom;
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom - padding.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,15 +315,16 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
self.width = targetSize.width;
|
||||
self.height = targetSize.height;
|
||||
CGFloat yStart = 0;
|
||||
DoricPadding padding = self.padding;
|
||||
CGFloat yStart = padding.top;
|
||||
if ((self.gravity & TOP) == TOP) {
|
||||
yStart = 0;
|
||||
yStart = padding.top;
|
||||
} else if ((self.gravity & BOTTOM) == BOTTOM) {
|
||||
yStart = targetSize.height - self.contentHeight;
|
||||
yStart = targetSize.height - self.contentHeight - padding.bottom;
|
||||
} else if ((self.gravity & CENTER_Y) == CENTER_Y) {
|
||||
yStart = (targetSize.height - self.contentHeight) / 2;
|
||||
yStart = (targetSize.height - self.contentHeight - padding.top - padding.bottom) / 2 + padding.top;
|
||||
}
|
||||
CGFloat remain = targetSize.height - self.contentHeight;
|
||||
CGFloat remain = targetSize.height - self.contentHeight - padding.top - padding.bottom;
|
||||
for (UIView *child in self.subviews) {
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
@@ -313,24 +337,26 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
childConfig = [DoricLayoutConfig new];
|
||||
}
|
||||
|
||||
CGSize size = [child measureSize:CGSizeMake(targetSize.width, targetSize.height - yStart)];
|
||||
CGSize size = [child measureSize:CGSizeMake(
|
||||
targetSize.width - padding.left - padding.right,
|
||||
targetSize.height - yStart - padding.bottom)];
|
||||
if (childConfig.weight) {
|
||||
size.height += remain / self.contentWeight * childConfig.weight;
|
||||
}
|
||||
[child layoutSelf:size];
|
||||
DoricGravity gravity = childConfig.alignment | self.gravity;
|
||||
if ((gravity & LEFT) == LEFT) {
|
||||
child.left = 0;
|
||||
child.left = padding.left;
|
||||
} else if ((gravity & RIGHT) == RIGHT) {
|
||||
child.right = self.width;
|
||||
child.right = self.width - padding.right;
|
||||
} else if ((gravity & CENTER_X) == CENTER_X) {
|
||||
child.centerX = targetSize.width / 2;
|
||||
} else if (childConfig.margin.left) {
|
||||
child.left = childConfig.margin.left + padding.left;
|
||||
} else if (childConfig.margin.right) {
|
||||
child.right = targetSize.width - childConfig.margin.right - padding.right;
|
||||
} else {
|
||||
if (childConfig.margin.left) {
|
||||
child.left = childConfig.margin.left;
|
||||
} else if (childConfig.margin.right) {
|
||||
child.right = targetSize.width - childConfig.margin.right;
|
||||
}
|
||||
child.left = padding.left;
|
||||
}
|
||||
if (childConfig.margin.top) {
|
||||
yStart += childConfig.margin.top;
|
||||
@@ -380,17 +406,16 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
self.width = targetSize.width;
|
||||
self.height = targetSize.height;
|
||||
CGFloat xStart = 0;
|
||||
if (self.contentWeight) {
|
||||
xStart = 0;
|
||||
} else if ((self.gravity & LEFT) == LEFT) {
|
||||
xStart = 0;
|
||||
DoricPadding padding = self.padding;
|
||||
CGFloat xStart = padding.left;
|
||||
if ((self.gravity & LEFT) == LEFT) {
|
||||
xStart = padding.left;
|
||||
} else if ((self.gravity & RIGHT) == RIGHT) {
|
||||
xStart = targetSize.width - self.contentWidth;
|
||||
xStart = targetSize.width - self.contentWidth - padding.right;
|
||||
} else if ((self.gravity & CENTER_X) == CENTER_X) {
|
||||
xStart = (targetSize.width - self.contentWidth) / 2;
|
||||
xStart = (targetSize.width - self.contentWidth - padding.left - padding.right) / 2 + padding.left;
|
||||
}
|
||||
CGFloat remain = targetSize.width - self.contentWidth;
|
||||
CGFloat remain = targetSize.width - self.contentWidth - padding.left - padding.right;
|
||||
for (UIView *child in self.subviews) {
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
@@ -403,7 +428,9 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
childConfig = [DoricLayoutConfig new];
|
||||
}
|
||||
|
||||
CGSize size = [child measureSize:CGSizeMake(targetSize.width - xStart, targetSize.height)];
|
||||
CGSize size = [child measureSize:CGSizeMake(
|
||||
targetSize.width - xStart - padding.right,
|
||||
targetSize.height - padding.top - padding.bottom)];
|
||||
if (childConfig.weight) {
|
||||
size.width += remain / self.contentWeight * childConfig.weight;
|
||||
}
|
||||
@@ -412,17 +439,17 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
|
||||
DoricGravity gravity = childConfig.alignment | self.gravity;
|
||||
if ((gravity & TOP) == TOP) {
|
||||
child.top = 0;
|
||||
child.top = padding.top;
|
||||
} else if ((gravity & BOTTOM) == BOTTOM) {
|
||||
child.bottom = targetSize.height;
|
||||
child.bottom = targetSize.height - padding.bottom;
|
||||
} else if ((gravity & CENTER_Y) == CENTER_Y) {
|
||||
child.centerY = targetSize.height / 2;
|
||||
} else if (childConfig.margin.top) {
|
||||
child.top = childConfig.margin.top + padding.top;
|
||||
} else if (childConfig.margin.bottom) {
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom - padding.bottom;
|
||||
} else {
|
||||
if (childConfig.margin.top) {
|
||||
child.top = childConfig.margin.top;
|
||||
} else if (childConfig.margin.bottom) {
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom;
|
||||
}
|
||||
child.top = padding.top;
|
||||
}
|
||||
|
||||
if (childConfig.margin.left) {
|
||||
|
@@ -62,6 +62,10 @@ @interface DoricListNode () <UITableViewDataSource, UITableViewDelegate>
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSNumber *> *itemHeights;
|
||||
@property(nonatomic, assign) NSUInteger itemCount;
|
||||
@property(nonatomic, assign) NSUInteger batchCount;
|
||||
@property(nonatomic, copy) NSString *onLoadMoreFuncId;
|
||||
@property(nonatomic, copy) NSString *renderItemFuncId;
|
||||
@property(nonatomic, copy) NSString *loadMoreViewId;
|
||||
@property(nonatomic, assign) BOOL loadMore;
|
||||
@end
|
||||
|
||||
@implementation DoricListNode
|
||||
@@ -86,6 +90,7 @@ - (UITableView *)build {
|
||||
it.dataSource = self;
|
||||
it.delegate = self;
|
||||
it.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
it.allowsSelection = NO;
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -94,11 +99,22 @@ - (void)blendView:(UITableView *)view forPropName:(NSString *)name propValue:(id
|
||||
self.itemCount = [prop unsignedIntegerValue];
|
||||
[self.view reloadData];
|
||||
} else if ([@"renderItem" isEqualToString:name]) {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
if (![self.renderItemFuncId isEqualToString:prop]) {
|
||||
self.renderItemFuncId = prop;
|
||||
[self.itemViewIds.allValues forEach:^(NSString *obj) {
|
||||
[self removeSubModel:obj];
|
||||
}];
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self.view reloadData];
|
||||
}
|
||||
} else if ([@"batchCount" isEqualToString:name]) {
|
||||
self.batchCount = [prop unsignedIntegerValue];
|
||||
} else if ([@"onLoadMore" isEqualToString:name]) {
|
||||
self.onLoadMoreFuncId = prop;
|
||||
} else if ([@"loadMoreView" isEqualToString:name]) {
|
||||
self.loadMoreViewId = prop;
|
||||
} else if ([@"loadMore" isEqualToString:name]) {
|
||||
self.loadMore = [prop boolValue];
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
@@ -109,7 +125,7 @@ - (void)blend:(NSDictionary *)props {
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.itemCount;
|
||||
return self.itemCount + (self.loadMore ? 1 : 0);
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
@@ -117,7 +133,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
|
||||
NSDictionary *model = [self itemModelAt:position];
|
||||
NSDictionary *props = model[@"props"];
|
||||
NSString *reuseId = props[@"identifier"];
|
||||
|
||||
if (position > 0 && position >= self.itemCount && self.onLoadMoreFuncId) {
|
||||
reuseId = @"doricLoadMoreCell";
|
||||
[self callJSResponse:self.onLoadMoreFuncId, nil];
|
||||
}
|
||||
DoricTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId ?: @"doriccell"];
|
||||
if (!cell) {
|
||||
cell = [[DoricTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId ?: @"doriccell"];
|
||||
@@ -147,6 +166,9 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
|
||||
}
|
||||
|
||||
- (NSDictionary *)itemModelAt:(NSUInteger)position {
|
||||
if (position >= self.itemCount) {
|
||||
return [self subModelOf:self.loadMoreViewId];
|
||||
}
|
||||
NSString *viewId = self.itemViewIds[@(position)];
|
||||
if (viewId && viewId.length > 0) {
|
||||
return [self subModelOf:viewId];
|
||||
@@ -160,29 +182,37 @@ - (NSDictionary *)itemModelAt:(NSUInteger)position {
|
||||
NSUInteger pos = position + idx;
|
||||
self.itemViewIds[@(pos)] = thisViewId;
|
||||
}];
|
||||
return array[0];
|
||||
if (array.count > 0) {
|
||||
return array[0];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
///Here async blend sub node because the item count need to be applied first.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
}];
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
- (void)callItem:(NSUInteger)position height:(CGFloat)height {
|
||||
|
24
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.h
Normal file
24
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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/12/7.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DoricGroupNode.h"
|
||||
|
||||
@interface DoricNestedSliderNode : DoricGroupNode<UIScrollView *>
|
||||
@end
|
101
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m
Normal file
101
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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/12/7.
|
||||
//
|
||||
|
||||
#import "DoricNestedSliderNode.h"
|
||||
#import "Doric.h"
|
||||
|
||||
@interface DoricNestedSliderView : UIScrollView
|
||||
|
||||
@end
|
||||
|
||||
@implementation DoricNestedSliderView
|
||||
- (CGSize)sizeThatFits:(CGSize)size {
|
||||
if (self.subviews.count > 0) {
|
||||
CGFloat width = size.width;
|
||||
CGFloat height = size.height;
|
||||
for (UIView *child in self.subviews) {
|
||||
CGSize childSize = [child measureSize:size];
|
||||
width = MAX(childSize.width, width);
|
||||
height = MAX(childSize.height, height);
|
||||
}
|
||||
return CGSizeMake(width, height);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
[super layoutSelf:targetSize];
|
||||
[self.subviews forEachIndexed:^(__kindof UIView *obj, NSUInteger idx) {
|
||||
obj.left = idx * self.width;
|
||||
}];
|
||||
[self setContentSize:CGSizeMake(self.subviews.count * self.width, self.height)];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface DoricNestedSliderNode () <UIScrollViewDelegate>
|
||||
@property(nonatomic, copy) NSString *onPageSelectedFuncId;
|
||||
@property(nonatomic, assign) NSUInteger lastPosition;
|
||||
@end
|
||||
|
||||
@implementation DoricNestedSliderNode
|
||||
- (UIScrollView *)build {
|
||||
return [[DoricNestedSliderView new] also:^(DoricNestedSliderView *it) {
|
||||
it.delegate = self;
|
||||
it.pagingEnabled = YES;
|
||||
[it setShowsVerticalScrollIndicator:NO];
|
||||
[it setShowsHorizontalScrollIndicator:NO];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)blendView:(UIScrollView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||
if ([@"onPageSlided" isEqualToString:name]) {
|
||||
self.onPageSelectedFuncId = prop;
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
|
||||
NSUInteger pageIndex = (NSUInteger) (scrollView.contentOffset.x / scrollView.width);
|
||||
[scrollView setContentOffset:CGPointMake(pageIndex * scrollView.width, scrollView.contentOffset.y) animated:YES];
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
if (pageIndex != self.lastPosition) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
self.lastPosition = pageIndex;
|
||||
}
|
||||
|
||||
|
||||
- (void)slidePage:(NSDictionary *)params withPromise:(DoricPromise *)promise {
|
||||
NSUInteger pageIndex = [params[@"page"] unsignedIntegerValue];
|
||||
BOOL smooth = [params[@"smooth"] boolValue];
|
||||
[self.view setContentOffset:CGPointMake(pageIndex * self.view.width, self.view.contentOffset.y) animated:smooth];
|
||||
[promise resolve:nil];
|
||||
self.lastPosition = pageIndex;
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)getSlidedPage {
|
||||
NSUInteger pageIndex = (NSUInteger) (self.view.contentOffset.x / self.view.width);
|
||||
return @(pageIndex);
|
||||
}
|
||||
@end
|
@@ -54,7 +54,11 @@ @interface DoricScrollerNode ()
|
||||
|
||||
@implementation DoricScrollerNode
|
||||
- (DoricScrollView *)build {
|
||||
return [DoricScrollView new];
|
||||
return [[DoricScrollView new] also:^(DoricScrollView *it) {
|
||||
if (@available(iOS 11, *)) {
|
||||
it.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
||||
|
@@ -35,6 +35,9 @@ @interface DoricSliderNode () <UICollectionViewDataSource, UICollectionViewDeleg
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSString *> *itemViewIds;
|
||||
@property(nonatomic, assign) NSUInteger itemCount;
|
||||
@property(nonatomic, assign) NSUInteger batchCount;
|
||||
@property(nonatomic, copy) NSString *onPageSelectedFuncId;
|
||||
@property(nonatomic, assign) NSUInteger lastPosition;
|
||||
@property(nonatomic, copy) NSString *renderPageFuncId;
|
||||
@end
|
||||
|
||||
@interface DoricSliderView : UICollectionView
|
||||
@@ -90,11 +93,18 @@ - (void)blendView:(UICollectionView *)view forPropName:(NSString *)name propValu
|
||||
self.itemCount = [prop unsignedIntegerValue];
|
||||
[self.view reloadData];
|
||||
} else if ([@"renderPage" isEqualToString:name]) {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
if ([self.renderPageFuncId isEqualToString:prop]) {
|
||||
|
||||
} else {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
self.renderPageFuncId = prop;
|
||||
}
|
||||
} else if ([@"batchCount" isEqualToString:name]) {
|
||||
self.batchCount = [prop unsignedIntegerValue];
|
||||
} else if ([@"onPageSlided" isEqualToString:name]) {
|
||||
self.onPageSelectedFuncId = prop;
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
@@ -197,5 +207,28 @@ - (void)blendSubNode:(NSDictionary *)subModel {
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
|
||||
NSUInteger pageIndex = (NSUInteger) (scrollView.contentOffset.x / scrollView.width);
|
||||
scrollView.contentOffset = CGPointMake(pageIndex * scrollView.width, scrollView.contentOffset.y);
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
if (pageIndex != self.lastPosition) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
self.lastPosition = pageIndex;
|
||||
}
|
||||
|
||||
- (void)slidePage:(NSDictionary *)params withPromise:(DoricPromise *)promise {
|
||||
NSUInteger pageIndex = [params[@"page"] unsignedIntegerValue];
|
||||
BOOL smooth = [params[@"smooth"] boolValue];
|
||||
[self.view setContentOffset:CGPointMake(pageIndex * self.view.width, self.view.contentOffset.y) animated:smooth];
|
||||
[promise resolve:nil];
|
||||
self.lastPosition = pageIndex;
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)getSlidedPage {
|
||||
NSUInteger pageIndex = (NSUInteger) (self.view.contentOffset.x / self.view.width);
|
||||
return @(pageIndex);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -35,6 +35,8 @@
|
||||
|
||||
- (void)clearSubModel;
|
||||
|
||||
- (void)removeSubModel:(NSString *)viewId;
|
||||
|
||||
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId;
|
||||
|
||||
- (void)recursiveMixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel;
|
||||
|
@@ -62,7 +62,6 @@ - (void)mixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
|
||||
targetProp[key] = obj;
|
||||
}
|
||||
}];
|
||||
targetModel[@"props"] = targetProp;
|
||||
}
|
||||
|
||||
- (void)recursiveMixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
|
||||
@@ -149,11 +148,16 @@ - (void)clearSubModel {
|
||||
[self.subNodes removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)removeSubModel:(NSString *)viewId {
|
||||
[self.subNodes removeObjectForKey:viewId];
|
||||
}
|
||||
|
||||
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
|
||||
NSAssert(NO, @"Should override class:%@ ,method:%@.", NSStringFromClass([self class]),
|
||||
NSStringFromSelector(_cmd));
|
||||
NSStringFromSelector(_cmd));
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)requestLayout {
|
||||
[self.view setNeedsLayout];
|
||||
}
|
||||
|
@@ -48,6 +48,8 @@ - (void)blendView:(UILabel *)view forPropName:(NSString *)name propValue:(id)pro
|
||||
alignment = NSTextAlignmentRight;
|
||||
}
|
||||
view.textAlignment = alignment;
|
||||
} else if ([name isEqualToString:@"maxLines"]) {
|
||||
view.numberOfLines = [prop integerValue];
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
|
@@ -235,7 +235,6 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
||||
} else {
|
||||
view.clipsToBounds = YES;
|
||||
}
|
||||
|
||||
} else if ([name isEqualToString:@"translationX"]) {
|
||||
self.translationX = prop;
|
||||
} else if ([name isEqualToString:@"translationY"]) {
|
||||
@@ -250,6 +249,19 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
||||
self.pivotY = prop;
|
||||
} else if ([name isEqualToString:@"rotation"]) {
|
||||
self.rotation = prop;
|
||||
} else if ([name isEqualToString:@"padding"]) {
|
||||
DoricPadding padding;
|
||||
padding.left = padding.right = padding.top = padding.bottom = 0;
|
||||
if ([prop isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *dictionary = prop;
|
||||
padding.left = [dictionary[@"left"] floatValue];
|
||||
padding.right = [dictionary[@"right"] floatValue];
|
||||
padding.top = [dictionary[@"top"] floatValue];
|
||||
padding.bottom = [dictionary[@"bottom"] floatValue];
|
||||
}
|
||||
self.view.padding = padding;
|
||||
} else if ([name isEqualToString:@"hidden"]) {
|
||||
self.view.hidden = [prop boolValue];
|
||||
} else {
|
||||
DoricLog(@"Blend View error for View Type :%@, prop is %@", self.class, name);
|
||||
}
|
||||
@@ -305,6 +317,11 @@ - (NSNumber *)getHeight {
|
||||
return @(self.view.height);
|
||||
}
|
||||
|
||||
- (NSDictionary *)getLocationOnScreen {
|
||||
CGPoint point = [self.view convertPoint:CGPointMake(0, 0) toView:[UIApplication sharedApplication].windows.lastObject];
|
||||
return @{@"x": @(point.x), @"y": @(point.y)};
|
||||
}
|
||||
|
||||
- (void)blendLayoutConfig:(NSDictionary *)params {
|
||||
[params[@"widthSpec"] also:^(NSNumber *it) {
|
||||
if (it) {
|
||||
@@ -357,6 +374,8 @@ - (NSDictionary *)transformation {
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
#pragma animations
|
||||
|
||||
- (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
CAAnimation *animation = [self parseAnimation:params];
|
||||
AnimationCallback *originDelegate = animation.delegate;
|
||||
@@ -371,6 +390,7 @@ - (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
if (originDelegate) {
|
||||
originDelegate.endBlock(callback);
|
||||
}
|
||||
[self.view.layer removeAllAnimations];
|
||||
[self transformProperties];
|
||||
[promise resolve:self.transformation];
|
||||
};
|
||||
@@ -379,6 +399,8 @@ - (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
if (params[@"delay"]) {
|
||||
animation.beginTime = CACurrentMediaTime() + [params[@"delay"] floatValue] / 1000;
|
||||
}
|
||||
animation.removedOnCompletion = NO;
|
||||
animation.fillMode = kCAFillModeForwards;
|
||||
[self.view.layer addAnimation:animation forKey:nil];
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,7 @@ - (void)setupError:(NSException *)exception {
|
||||
}
|
||||
|
||||
- (BOOL)hasResult {
|
||||
return self.result;
|
||||
return self.result != nil;
|
||||
}
|
||||
|
||||
- (id)getResult {
|
||||
|
@@ -26,7 +26,7 @@ extern NSString *const DORIC_BUNDLE_SANDBOX;
|
||||
extern NSString *const DORIC_BUNDLE_LIB;
|
||||
extern NSString *const DORIC_MODULE_LIB;
|
||||
|
||||
|
||||
extern NSString *const INJECT_ENVIRONMENT;
|
||||
extern NSString *const INJECT_LOG;
|
||||
extern NSString *const INJECT_REQUIRE;
|
||||
extern NSString *const INJECT_TIMER_SET;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
NSString *const DORIC_BUNDLE_LIB = @"doric-lib";
|
||||
NSString *const DORIC_MODULE_LIB = @"doric";
|
||||
|
||||
NSString *const INJECT_ENVIRONMENT = @"Environment";
|
||||
|
||||
NSString *const INJECT_LOG = @"nativeLog";
|
||||
NSString *const INJECT_REQUIRE = @"nativeRequire";
|
||||
|
@@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
||||
DoricJSRemoteArgTypeNil = 0,
|
||||
DoricJSRemoteArgTypeInteger,
|
||||
DoricJSRemoteArgTypeNumber,
|
||||
DoricJSRemoteArgTypeBool,
|
||||
DoricJSRemoteArgTypeString,
|
||||
DoricJSRemoteArgTypeObject,
|
||||
@@ -20,4 +20,5 @@ typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
||||
|
||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg);
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@@ -6,7 +6,16 @@
|
||||
//
|
||||
|
||||
#import "DoricJSRemoteArgType.h"
|
||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg) {
|
||||
// TODO: 类型缺失
|
||||
return DoricJSRemoteArgTypeString;
|
||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg) {
|
||||
DoricJSRemoteArgType type = DoricJSRemoteArgTypeNil;
|
||||
if ([arg isKindOfClass:[NSNumber class]]) {
|
||||
type = DoricJSRemoteArgTypeNumber;
|
||||
}else if ([arg isKindOfClass:[NSString class]]) {
|
||||
type = DoricJSRemoteArgTypeString;
|
||||
}else if ([arg isKindOfClass:[NSDictionary class]]) {
|
||||
type = DoricJSRemoteArgTypeObject;
|
||||
}else if ([arg isKindOfClass:[NSMutableArray class]]) {
|
||||
type = DoricJSRemoteArgTypeArray;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
@@ -39,4 +39,4 @@ NSBundle *_Nonnull DoricBundle(void);
|
||||
|
||||
void ShowToast(NSString *_Nonnull text, DoricGravity gravity);
|
||||
|
||||
UIImage *_Nonnull UIImageWithColor(UIColor *color);
|
||||
UIImage *_Nonnull UIImageWithColor(UIColor * _Nonnull color);
|
||||
|
Reference in New Issue
Block a user