feat:add subview in iOS
This commit is contained in:
parent
bdabde2f56
commit
52fcafeb92
@ -67,7 +67,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
|||||||
if (id.equals(oldNode.getId())) {
|
if (id.equals(oldNode.getId())) {
|
||||||
//The same,skip
|
//The same,skip
|
||||||
} else {
|
} else {
|
||||||
//Find in remaining nodes
|
//Find in remain nodes
|
||||||
int position = -1;
|
int position = -1;
|
||||||
for (int start = idx + 1; start < mChildNodes.size(); start++) {
|
for (int start = idx + 1; start < mChildNodes.size(); start++) {
|
||||||
ViewNode node = mChildNodes.get(start);
|
ViewNode node = mChildNodes.get(start);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
@implementation DoricContextHolder
|
@implementation DoricContextHolder
|
||||||
|
|
||||||
- (instancetype)initWithContext:(DoricContext *)doricContext {
|
- (instancetype)initWithContext:(DoricContext *)doricContext {
|
||||||
if (self = [super init]) {
|
if (self = [self init]) {
|
||||||
_doricContext = doricContext;
|
_doricContext = doricContext;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -20,19 +20,11 @@
|
|||||||
// Created by pengfei.zhou on 2019/7/30.
|
// Created by pengfei.zhou on 2019/7/30.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "DoricViewNode.h"
|
#import "DoricSuperNode.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricGroupNode <V:UIView *, P:DoricLayoutConfig *> : DoricViewNode<V>
|
@interface DoricGroupNode <V:UIView *, P:DoricLayoutConfig *> : DoricSuperNode<V, P>
|
||||||
|
|
||||||
@property(nonatomic, strong) NSMutableDictionary *children;
|
|
||||||
@property(nonatomic, strong) NSMutableArray *indexedChildren;
|
|
||||||
|
|
||||||
|
|
||||||
- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig;
|
|
||||||
|
|
||||||
- (P)generateDefaultLayoutParams;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -23,124 +23,117 @@
|
|||||||
#import <Doric/DoricExtensions.h>
|
#import <Doric/DoricExtensions.h>
|
||||||
#import "DoricGroupNode.h"
|
#import "DoricGroupNode.h"
|
||||||
|
|
||||||
|
@interface DoricGroupNode ()
|
||||||
|
@property(nonatomic, copy) NSArray<DoricViewNode *> *childNodes;
|
||||||
|
@property(nonatomic, copy) NSArray <NSString *> *childViewIds;
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation DoricGroupNode
|
@implementation DoricGroupNode
|
||||||
|
|
||||||
- (instancetype)initWithContext:(DoricContext *)doricContext {
|
- (instancetype)initWithContext:(DoricContext *)doricContext {
|
||||||
if (self = [super initWithContext:doricContext]) {
|
if (self = [super initWithContext:doricContext]) {
|
||||||
_children = [[NSMutableDictionary alloc] init];
|
_childNodes = @[];
|
||||||
_indexedChildren = [[NSMutableArray alloc] init];
|
_childViewIds = @[];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIView *)build:(NSDictionary *)props {
|
- (UIView *)build {
|
||||||
UIView *ret = [[UIView alloc] init];
|
UIView *ret = [[UIView alloc] init];
|
||||||
ret.clipsToBounds = YES;
|
ret.clipsToBounds = YES;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
|
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||||
if ([name isEqualToString:@"children"]) {
|
if ([@"children" isEqualToString:name]) {
|
||||||
NSArray *array = prop;
|
self.childViewIds = prop;
|
||||||
NSInteger i;
|
|
||||||
NSMutableArray *tobeRemoved = [[NSMutableArray alloc] init];
|
|
||||||
for (i = 0; i < array.count; i++) {
|
|
||||||
NSDictionary *val = array[i];
|
|
||||||
if (!val || (NSNull *) val == [NSNull null]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
NSString *type = val[@"type"];
|
|
||||||
NSString *viewId = val[@"id"];
|
|
||||||
DoricViewNode *node = self.children[viewId];
|
|
||||||
if (node == nil) {
|
|
||||||
node = [DoricViewNode create:self.doricContext withType:type];
|
|
||||||
node.index = i;
|
|
||||||
node.parent = self;
|
|
||||||
node.viewId = viewId;
|
|
||||||
self.children[viewId] = node;
|
|
||||||
} else {
|
|
||||||
if (i != node.index) {
|
|
||||||
[self.indexedChildren removeObjectAtIndex:i];
|
|
||||||
node.index = i;
|
|
||||||
[node.view removeFromSuperview];
|
|
||||||
}
|
|
||||||
[tobeRemoved removeObject:node];
|
|
||||||
}
|
|
||||||
DoricViewNode *old = i >= self.indexedChildren.count ? nil : self.indexedChildren[i];
|
|
||||||
if (old && old != node) {
|
|
||||||
[old.view removeFromSuperview];
|
|
||||||
self.indexedChildren[i] = [NSNull null];
|
|
||||||
[tobeRemoved addObject:old];
|
|
||||||
}
|
|
||||||
|
|
||||||
DoricLayoutConfig *params = node.layoutConfig;
|
|
||||||
if (params == nil) {
|
|
||||||
params = [self generateDefaultLayoutParams];
|
|
||||||
node.layoutConfig = params;
|
|
||||||
}
|
|
||||||
[node blend:val[@"props"]];
|
|
||||||
if (self.indexedChildren.count <= i) {
|
|
||||||
[self.view addSubview:node.view];
|
|
||||||
[self.indexedChildren addObject:node];
|
|
||||||
} else if (self.indexedChildren[i] == [NSNull null]) {
|
|
||||||
self.indexedChildren[i] = node;
|
|
||||||
[self.view insertSubview:node.view atIndex:i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NSInteger start = i;
|
|
||||||
while (start < self.indexedChildren.count) {
|
|
||||||
DoricViewNode *node = self.indexedChildren[(NSUInteger) start];
|
|
||||||
if (node) {
|
|
||||||
[self.children removeObjectForKey:node.viewId];
|
|
||||||
[node.view removeFromSuperview];
|
|
||||||
[tobeRemoved removeObject:node];
|
|
||||||
}
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
if (i < self.indexedChildren.count) {
|
|
||||||
[self.indexedChildren removeObjectsInRange:NSMakeRange((NSUInteger) i, self.indexedChildren.count - i)];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DoricViewNode *node in tobeRemoved) {
|
|
||||||
[self.children removeObjectForKey:node.viewId];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
[super blendView:view forPropName:name propValue:prop];
|
[super blendView:view forPropName:name propValue:prop];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)blend:(NSDictionary *)props {
|
||||||
|
[super blend:props];
|
||||||
|
[self configChildNodes];
|
||||||
|
}
|
||||||
|
|
||||||
- (DoricLayoutConfig *)generateDefaultLayoutParams {
|
- (DoricLayoutConfig *)generateDefaultLayoutParams {
|
||||||
DoricLayoutConfig *params = [[DoricLayoutConfig alloc] init];
|
DoricLayoutConfig *params = [[DoricLayoutConfig alloc] init];
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig {
|
- (void)configChildNodes {
|
||||||
DoricLayoutConfig *params = child.layoutConfig;
|
NSMutableArray *childNodes = [self.childNodes mutableCopy];
|
||||||
|
for (NSUInteger idx = 0; idx < self.childViewIds.count; idx++) {
|
||||||
|
NSString *viewId = self.childViewIds[idx];
|
||||||
|
NSDictionary *model = [self subModelOf:viewId];
|
||||||
|
NSString *type = model[@"type"];
|
||||||
|
if (idx < self.childNodes.count) {
|
||||||
|
DoricViewNode *oldNode = childNodes[idx];
|
||||||
|
if ([viewId isEqualToString:oldNode.viewId]) {
|
||||||
|
///Same,skip
|
||||||
|
} else {
|
||||||
|
///Find in remain nodes
|
||||||
|
NSInteger position = -1;
|
||||||
|
for (NSUInteger start = idx + 1; start < childNodes.count; start++) {
|
||||||
|
DoricViewNode *node = childNodes[start];
|
||||||
|
if ([viewId isEqualToString:node.viewId]) {
|
||||||
|
position = start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (position >= 0) {
|
||||||
|
///Found ,swap idx,position
|
||||||
|
DoricViewNode *reused = childNodes[(NSUInteger) position];
|
||||||
|
[childNodes removeObjectAtIndex:(NSUInteger) position];
|
||||||
|
[childNodes removeObjectAtIndex:idx];
|
||||||
|
[childNodes insertObject:reused atIndex:idx];
|
||||||
|
[childNodes insertObject:oldNode atIndex:(NSUInteger) position];
|
||||||
|
|
||||||
[layoutConfig[@"widthSpec"] also:^(NSNumber *it) {
|
///View swap index
|
||||||
if (it) {
|
[reused.view removeFromSuperview];
|
||||||
params.widthSpec = (DoricLayoutSpec) [it integerValue];
|
[oldNode.view removeFromSuperview];
|
||||||
}
|
[self.view insertSubview:reused.view atIndex:idx];
|
||||||
}];
|
[self.view insertSubview:oldNode.view atIndex:position];
|
||||||
|
} else {
|
||||||
|
///Not found,insert
|
||||||
|
DoricViewNode *viewNode = [DoricViewNode create:self.doricContext withType:type];
|
||||||
|
viewNode.viewId = viewId;
|
||||||
|
[viewNode initWithSuperNode:self];
|
||||||
|
[viewNode blend:model[@"props"]];
|
||||||
|
[childNodes insertObject:viewNode atIndex:idx];
|
||||||
|
[self.view insertSubview:viewNode.view atIndex:idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[layoutConfig[@"heightSpec"] also:^(NSNumber *it) {
|
|
||||||
if (it) {
|
|
||||||
params.heightSpec = (DoricLayoutSpec) [it integerValue];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
if ([params isKindOfClass:DoricMarginConfig.class]) {
|
} else {
|
||||||
DoricMarginConfig *marginParams = (DoricMarginConfig *) params;
|
/// Insert
|
||||||
NSDictionary *margin = layoutConfig[@"margin"];
|
DoricViewNode *viewNode = [DoricViewNode create:self.doricContext withType:type];
|
||||||
if (margin) {
|
viewNode.viewId = viewId;
|
||||||
marginParams.margin = DoricMarginMake(
|
[viewNode initWithSuperNode:self];
|
||||||
[(NSNumber *) margin[@"left"] floatValue],
|
[viewNode blend:model[@"props"]];
|
||||||
[(NSNumber *) margin[@"top"] floatValue],
|
[childNodes addObject:viewNode];
|
||||||
[(NSNumber *) margin[@"right"] floatValue],
|
[self.view addSubview:viewNode.view];
|
||||||
[(NSNumber *) margin[@"bottom"] floatValue]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSUInteger count = childNodes.count;
|
||||||
|
for (NSUInteger idx = self.childViewIds.count; idx < count; idx++) {
|
||||||
|
DoricViewNode *viewNode = childNodes.lastObject;
|
||||||
|
[childNodes removeLastObject];
|
||||||
|
[viewNode.view removeFromSuperview];
|
||||||
|
}
|
||||||
|
self.childNodes = [childNodes copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||||
|
NSString *viewId = subModel[@"id"];
|
||||||
|
[self.childNodes enumerateObjectsUsingBlock:^(DoricViewNode *obj, NSUInteger idx, BOOL *stop) {
|
||||||
|
if ([viewId isEqualToString:obj.viewId]) {
|
||||||
|
[obj blend:subModel[@"props"]];
|
||||||
|
*stop = YES;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#import "DoricUtil.h"
|
#import "DoricUtil.h"
|
||||||
|
|
||||||
@implementation DoricHLayoutNode
|
@implementation DoricHLayoutNode
|
||||||
- (DoricHLayoutView *)build:(NSDictionary *)props {
|
- (DoricHLayoutView *)build {
|
||||||
return [DoricHLayoutView new];
|
return [DoricHLayoutView new];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,13 +38,13 @@ - (void)blendView:(DoricHLayoutView *)view forPropName:(NSString *)name propValu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig {
|
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig {
|
||||||
[super blendChild:child layoutConfig:layoutConfig];
|
[super blendSubNode:subNode layoutConfig:layoutConfig];
|
||||||
if (![child.layoutConfig isKindOfClass:DoricLinearConfig.class]) {
|
if (![subNode.layoutConfig isKindOfClass:DoricLinearConfig.class]) {
|
||||||
DoricLog(@"blend DoricHLayoutView child error,layout params not match");
|
DoricLog(@"blend DoricHLayoutView child error,layout params not match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DoricLinearConfig *params = (DoricLinearConfig *) child.layoutConfig;
|
DoricLinearConfig *params = (DoricLinearConfig *) subNode.layoutConfig;
|
||||||
NSDictionary *margin = layoutConfig[@"margin"];
|
NSDictionary *margin = layoutConfig[@"margin"];
|
||||||
if (margin) {
|
if (margin) {
|
||||||
params.margin = DoricMarginMake(
|
params.margin = DoricMarginMake(
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
@implementation DoricImageNode
|
@implementation DoricImageNode
|
||||||
|
|
||||||
- (UIImageView *)build:(NSDictionary *)props {
|
- (UIImageView *)build {
|
||||||
return [[UIImageView alloc] init];
|
return [[UIImageView alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
@implementation DoricRootNode
|
@implementation DoricRootNode
|
||||||
- (void)setupRootView:(DoricStackView *)view {
|
- (void)setupRootView:(DoricStackView *)view {
|
||||||
self.view = view;
|
self.view = view;
|
||||||
self.layoutConfig = view.layoutConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)render:(NSDictionary *)props {
|
- (void)render:(NSDictionary *)props {
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
@implementation DoricStackNode
|
@implementation DoricStackNode
|
||||||
|
|
||||||
- (DoricStackView *)build:(NSDictionary *)props {
|
- (DoricStackView *)build {
|
||||||
return [DoricStackView new];
|
return [DoricStackView new];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,13 +41,13 @@ - (DoricStackConfig *)generateDefaultLayoutParams {
|
|||||||
return [[DoricStackConfig alloc] init];
|
return [[DoricStackConfig alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig {
|
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig {
|
||||||
[super blendChild:child layoutConfig:layoutConfig];
|
[super blendSubNode:subNode layoutConfig:layoutConfig];
|
||||||
if (![child.layoutConfig isKindOfClass:DoricStackConfig.class]) {
|
if (![subNode.layoutConfig isKindOfClass:DoricStackConfig.class]) {
|
||||||
DoricLog(@"blend DoricHLayoutView child error,layout params not match");
|
DoricLog(@"blend DoricHLayoutView child error,layout params not match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DoricStackConfig *params = (DoricStackConfig *) child.layoutConfig;
|
DoricStackConfig *params = (DoricStackConfig *) subNode.layoutConfig;
|
||||||
NSNumber *alignment = layoutConfig[@"alignment"];
|
NSNumber *alignment = layoutConfig[@"alignment"];
|
||||||
if (alignment) {
|
if (alignment) {
|
||||||
params.alignment = (DoricGravity) [alignment integerValue];
|
params.alignment = (DoricGravity) [alignment integerValue];
|
||||||
|
35
iOS/Pod/Classes/Shader/DoricSuperNode.h
Normal file
35
iOS/Pod/Classes/Shader/DoricSuperNode.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "DoricViewNode.h"
|
||||||
|
|
||||||
|
@interface DoricSuperNode<V:UIView *, P:DoricLayoutConfig *> : DoricViewNode<V>
|
||||||
|
- (P)generateDefaultLayoutParams;
|
||||||
|
|
||||||
|
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig;
|
||||||
|
|
||||||
|
- (void)blendSubNode:(NSDictionary *)subModel;
|
||||||
|
|
||||||
|
- (NSDictionary *)subModelOf:(NSString *)viewId;
|
||||||
|
|
||||||
|
- (void)setSubModel:(NSDictionary *)model in:(NSString *)viewId;
|
||||||
|
|
||||||
|
- (void)clearSubModel;
|
||||||
|
@end
|
117
iOS/Pod/Classes/Shader/DoricSuperNode.m
Normal file
117
iOS/Pod/Classes/Shader/DoricSuperNode.m
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* 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/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "DoricSuperNode.h"
|
||||||
|
#import "DoricExtensions.h"
|
||||||
|
|
||||||
|
@interface DoricSuperNode ()
|
||||||
|
@property(nonatomic, strong) NSMutableDictionary <NSString *, NSMutableDictionary *> *subNodes;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DoricSuperNode
|
||||||
|
- (instancetype)initWithContext:(DoricContext *)doricContext {
|
||||||
|
if (self = [super initWithContext:doricContext]) {
|
||||||
|
_subNodes = [NSMutableDictionary new];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||||
|
if ([@"subviews" isEqualToString:name]) {
|
||||||
|
NSArray *subviews = prop;
|
||||||
|
for (NSDictionary *subModel in subviews) {
|
||||||
|
[self mixinSubNode:subModel];
|
||||||
|
[self blendSubNode:subModel];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mixinSubNode:(NSDictionary *)dictionary {
|
||||||
|
NSString *viewId = dictionary[@"id"];
|
||||||
|
NSMutableDictionary *oldModel = self.subNodes[viewId];
|
||||||
|
if (oldModel) {
|
||||||
|
[self mixin:dictionary to:oldModel];
|
||||||
|
} else {
|
||||||
|
self.subNodes[viewId] = [dictionary mutableCopy];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
|
||||||
|
NSDictionary *srcProp = srcModel[@"props"];
|
||||||
|
NSMutableDictionary *targetProp = [targetModel[@"props"] mutableCopy];
|
||||||
|
[srcProp enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
|
||||||
|
if (![@"subviews" isEqualToString:key]) {
|
||||||
|
targetProp[key] = obj;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
targetModel[@"props"] = [targetProp copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig {
|
||||||
|
DoricLayoutConfig *params = subNode.layoutConfig;
|
||||||
|
|
||||||
|
[layoutConfig[@"widthSpec"] also:^(NSNumber *it) {
|
||||||
|
if (it) {
|
||||||
|
params.widthSpec = (DoricLayoutSpec) [it integerValue];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
[layoutConfig[@"heightSpec"] also:^(NSNumber *it) {
|
||||||
|
if (it) {
|
||||||
|
params.heightSpec = (DoricLayoutSpec) [it integerValue];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
if ([params isKindOfClass:DoricMarginConfig.class]) {
|
||||||
|
DoricMarginConfig *marginParams = (DoricMarginConfig *) params;
|
||||||
|
NSDictionary *margin = layoutConfig[@"margin"];
|
||||||
|
if (margin) {
|
||||||
|
marginParams.margin = DoricMarginMake(
|
||||||
|
[(NSNumber *) margin[@"left"] floatValue],
|
||||||
|
[(NSNumber *) margin[@"top"] floatValue],
|
||||||
|
[(NSNumber *) margin[@"right"] floatValue],
|
||||||
|
[(NSNumber *) margin[@"bottom"] floatValue]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||||
|
NSAssert(NO, @"Should override class:%@ ,method:%@.", NSStringFromClass([self class]),
|
||||||
|
NSStringFromSelector(_cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
- (DoricLayoutConfig *)generateDefaultLayoutParams {
|
||||||
|
DoricLayoutConfig *params = [[DoricLayoutConfig alloc] init];
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (NSDictionary *)subModelOf:(NSString *)viewId {
|
||||||
|
return self.subNodes[viewId];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSubModel:(NSDictionary *)model in:(NSString *)viewId {
|
||||||
|
self.subNodes[viewId] = [model mutableCopy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearSubModel {
|
||||||
|
[self.subNodes removeAllObjects];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -25,7 +25,7 @@
|
|||||||
#import "DoricGroupNode.h"
|
#import "DoricGroupNode.h"
|
||||||
|
|
||||||
@implementation DoricTextNode
|
@implementation DoricTextNode
|
||||||
- (id)build:(NSDictionary *)props {
|
- (UILabel *)build {
|
||||||
return [[UILabel alloc] init];
|
return [[UILabel alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
@implementation DoricVLayoutNode
|
@implementation DoricVLayoutNode
|
||||||
|
|
||||||
- (DoricVLayoutView *)build:(NSDictionary *)props {
|
- (DoricVLayoutView *)build {
|
||||||
return [DoricVLayoutView new];
|
return [DoricVLayoutView new];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,13 +39,13 @@ - (void)blendView:(DoricVLayoutView *)view forPropName:(NSString *)name propValu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig {
|
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutconfig {
|
||||||
[super blendChild:child layoutConfig:layoutconfig];
|
[super blendSubNode:subNode layoutConfig:layoutconfig];
|
||||||
if (![child.layoutConfig isKindOfClass:DoricLinearConfig.class]) {
|
if (![subNode.layoutConfig isKindOfClass:DoricLinearConfig.class]) {
|
||||||
DoricLog(@"blend DoricVLayoutView child error,layout params not match");
|
DoricLog(@"blend DoricVLayoutView child error,layout params not match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DoricLinearConfig *params = (DoricLinearConfig *) child.layoutConfig;
|
DoricLinearConfig *params = (DoricLinearConfig *) subNode.layoutConfig;
|
||||||
NSDictionary *margin = layoutconfig[@"margin"];
|
NSDictionary *margin = layoutconfig[@"margin"];
|
||||||
if (margin) {
|
if (margin) {
|
||||||
params.margin = DoricMarginMake(
|
params.margin = DoricMarginMake(
|
||||||
|
@ -25,22 +25,24 @@
|
|||||||
#import "UIView+Doric.h"
|
#import "UIView+Doric.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
@class DoricGroupNode;
|
@class DoricSuperNode;
|
||||||
|
|
||||||
@interface DoricViewNode <V:UIView *> : DoricContextHolder
|
@interface DoricViewNode <V:UIView *> : DoricContextHolder
|
||||||
|
|
||||||
@property(nonatomic, strong) V view;
|
@property(nonatomic, strong) V view;
|
||||||
|
|
||||||
@property(nonatomic, weak) DoricGroupNode *parent;
|
@property(nonatomic, weak) DoricSuperNode *superNode;
|
||||||
@property(nonatomic) NSInteger index;
|
@property(nonatomic) NSInteger index;
|
||||||
|
|
||||||
@property(nonatomic, strong) NSString *viewId;
|
@property(nonatomic, copy) NSString *viewId;
|
||||||
|
|
||||||
@property(nonatomic, strong) DoricLayoutConfig *layoutConfig;
|
@property(nonatomic, readonly) DoricLayoutConfig *layoutConfig;
|
||||||
|
|
||||||
@property(nonatomic, strong, readonly) NSArray<NSString *> *idList;
|
@property(nonatomic, readonly) NSArray<NSString *> *idList;
|
||||||
|
|
||||||
- (V)build:(NSDictionary *)props;
|
- (void)initWithSuperNode:(DoricSuperNode *)superNode;
|
||||||
|
|
||||||
|
- (V)build;
|
||||||
|
|
||||||
- (void)blend:(NSDictionary *)props;
|
- (void)blend:(NSDictionary *)props;
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#import "DoricGroupNode.h"
|
#import "DoricGroupNode.h"
|
||||||
#import "DoricRootNode.h"
|
#import "DoricRootNode.h"
|
||||||
#import "DoricConstant.h"
|
#import "DoricConstant.h"
|
||||||
|
#import "DoricSuperNode.h"
|
||||||
|
#import "DoricExtensions.h"
|
||||||
|
|
||||||
void DoricAddEllipticArcPath(CGMutablePathRef path,
|
void DoricAddEllipticArcPath(CGMutablePathRef path,
|
||||||
CGPoint origin,
|
CGPoint origin,
|
||||||
@ -77,14 +79,23 @@ - (instancetype)initWithContext:(DoricContext *)doricContext {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIView *)build:(NSDictionary *)props {
|
|
||||||
|
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
||||||
|
self.superNode = superNode;
|
||||||
|
self.view = [[self build] also:^(UIView *it) {
|
||||||
|
it.layoutConfig = [superNode generateDefaultLayoutParams];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (DoricLayoutConfig *)layoutConfig {
|
||||||
|
return self.view.layoutConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)build {
|
||||||
return [[UIView alloc] init];
|
return [[UIView alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)blend:(NSDictionary *)props {
|
- (void)blend:(NSDictionary *)props {
|
||||||
if (self.view == nil) {
|
|
||||||
self.view = [self build:props];
|
|
||||||
}
|
|
||||||
self.view.layoutConfig = self.layoutConfig;
|
self.view.layoutConfig = self.layoutConfig;
|
||||||
for (NSString *key in props) {
|
for (NSString *key in props) {
|
||||||
id value = props[key];
|
id value = props[key];
|
||||||
@ -110,8 +121,8 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
|||||||
} else if ([name isEqualToString:@"bgColor"]) {
|
} else if ([name isEqualToString:@"bgColor"]) {
|
||||||
view.backgroundColor = DoricColor(prop);
|
view.backgroundColor = DoricColor(prop);
|
||||||
} else if ([name isEqualToString:@"layoutConfig"]) {
|
} else if ([name isEqualToString:@"layoutConfig"]) {
|
||||||
if (self.parent && [prop isKindOfClass:[NSDictionary class]]) {
|
if (self.superNode && [prop isKindOfClass:[NSDictionary class]]) {
|
||||||
[self.parent blendChild:self layoutConfig:prop];
|
[self.superNode blendSubNode:self layoutConfig:prop];
|
||||||
}
|
}
|
||||||
} else if ([name isEqualToString:@"onClick"]) {
|
} else if ([name isEqualToString:@"onClick"]) {
|
||||||
self.callbackIds[@"onClick"] = prop;
|
self.callbackIds[@"onClick"] = prop;
|
||||||
@ -176,7 +187,7 @@ - (void)onClick:(UIView *)view {
|
|||||||
DoricViewNode *node = self;
|
DoricViewNode *node = self;
|
||||||
do {
|
do {
|
||||||
[ret addObject:node.viewId];
|
[ret addObject:node.viewId];
|
||||||
node = node.parent;
|
node = node.superNode;
|
||||||
} while (node && ![node isKindOfClass:[DoricRootNode class]]);
|
} while (node && ![node isKindOfClass:[DoricRootNode class]]);
|
||||||
|
|
||||||
return [[ret reverseObjectEnumerator] allObjects];
|
return [[ret reverseObjectEnumerator] allObjects];
|
||||||
@ -203,7 +214,7 @@ + (DoricViewNode *)create:(DoricContext *)context withType:(NSString *)type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)requestLayout {
|
- (void)requestLayout {
|
||||||
[self.parent requestLayout];
|
[self.superNode requestLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -26,7 +26,7 @@ void DoricLog(NSString *_Nonnull format, ...);
|
|||||||
|
|
||||||
UIColor *_Nonnull DoricColor(NSNumber *_Nonnull number);
|
UIColor *_Nonnull DoricColor(NSNumber *_Nonnull number);
|
||||||
|
|
||||||
NSBundle *DoricBundle();
|
NSBundle *_Nonnull DoricBundle(void);
|
||||||
|
|
||||||
#ifndef DC_LOCK
|
#ifndef DC_LOCK
|
||||||
#define DC_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
|
#define DC_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
|
||||||
|
Reference in New Issue
Block a user