From db55cb30fb64cf30be5ebfc2e5c3ece04fd037c0 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Sat, 16 Nov 2019 15:10:21 +0800 Subject: [PATCH] feat:fix ListView's auto resize height in iOS --- demo/src/ListDemo.ts | 6 +- iOS/Pod/Classes/Shader/DoricLayouts.h | 4 ++ iOS/Pod/Classes/Shader/DoricLayouts.m | 4 -- iOS/Pod/Classes/Shader/DoricListItemNode.h | 3 +- iOS/Pod/Classes/Shader/DoricListItemNode.m | 23 +++++++- iOS/Pod/Classes/Shader/DoricListNode.h | 2 +- iOS/Pod/Classes/Shader/DoricListNode.m | 66 +++++++++++++++++----- 7 files changed, 80 insertions(+), 28 deletions(-) diff --git a/demo/src/ListDemo.ts b/demo/src/ListDemo.ts index df14fee2..843ab12c 100644 --- a/demo/src/ListDemo.ts +++ b/demo/src/ListDemo.ts @@ -32,8 +32,8 @@ class ListPanel extends Panel { heightSpec: LayoutSpec.WRAP_CONTENT, margin: { left: 10, - right: 10, - top: 10, + right: 50, + top: 50, bottom: 10, }, }, @@ -48,7 +48,7 @@ class ListPanel extends Panel { widthSpec: LayoutSpec.AT_MOST, heightSpec: LayoutSpec.EXACTLY, } - it.height = 50 + it.height = 100 it.onClick = () => { log(`Click item at ${idx}`) it.bgColor = Color.parse('#000000') diff --git a/iOS/Pod/Classes/Shader/DoricLayouts.h b/iOS/Pod/Classes/Shader/DoricLayouts.h index dbae4c21..33c3ea86 100644 --- a/iOS/Pod/Classes/Shader/DoricLayouts.h +++ b/iOS/Pod/Classes/Shader/DoricLayouts.h @@ -69,6 +69,10 @@ typedef NS_ENUM(NSInteger, DoricGravity) { @interface DoricLayoutContainer : UIView @property(nonatomic, assign) DoricGravity gravity; + +- (void)layout:(CGSize)targetSize; + +- (CGSize)sizeContent:(CGSize)size; @end @interface DoricStackView : DoricLayoutContainer diff --git a/iOS/Pod/Classes/Shader/DoricLayouts.m b/iOS/Pod/Classes/Shader/DoricLayouts.m index b073cac7..fca3fe87 100644 --- a/iOS/Pod/Classes/Shader/DoricLayouts.m +++ b/iOS/Pod/Classes/Shader/DoricLayouts.m @@ -62,10 +62,6 @@ @interface DoricLayoutContainer () @property(nonatomic, assign) CGFloat contentWidth; @property(nonatomic, assign) CGFloat contentHeight; @property(nonatomic, assign) NSUInteger contentWeight; - -- (void)layout:(CGSize)targetSize; - -- (CGSize)sizeContent:(CGSize)size; @end @implementation DoricLayoutContainer diff --git a/iOS/Pod/Classes/Shader/DoricListItemNode.h b/iOS/Pod/Classes/Shader/DoricListItemNode.h index ded76f48..a5f5c720 100644 --- a/iOS/Pod/Classes/Shader/DoricListItemNode.h +++ b/iOS/Pod/Classes/Shader/DoricListItemNode.h @@ -21,6 +21,5 @@ #import "DoricStackNode.h" -@interface DoricListItemNode : DoricGroupNode - +@interface DoricListItemNode : DoricStackNode @end \ No newline at end of file diff --git a/iOS/Pod/Classes/Shader/DoricListItemNode.m b/iOS/Pod/Classes/Shader/DoricListItemNode.m index bba08457..db72ab85 100644 --- a/iOS/Pod/Classes/Shader/DoricListItemNode.m +++ b/iOS/Pod/Classes/Shader/DoricListItemNode.m @@ -18,10 +18,27 @@ // #import "DoricListItemNode.h" +#import "DoricExtensions.h" + +@interface DoricListItemNode () +@end + +@interface DoricListItemView : DoricStackView +@end + +@implementation DoricListItemView +@end @implementation DoricListItemNode -- (UITableViewCell *)build { - return nil; +- (instancetype)initWithContext:(DoricContext *)doricContext { + if (self = [super initWithContext:doricContext]) { + self.reusable = YES; + } + return self; } -@end \ No newline at end of file + +- (DoricStackView *)build { + return [DoricListItemView new]; +} +@end diff --git a/iOS/Pod/Classes/Shader/DoricListNode.h b/iOS/Pod/Classes/Shader/DoricListNode.h index 55750e4b..97244086 100644 --- a/iOS/Pod/Classes/Shader/DoricListNode.h +++ b/iOS/Pod/Classes/Shader/DoricListNode.h @@ -19,6 +19,6 @@ #import #import "DoricSuperNode.h" -@interface DoricListNode : DoricSuperNode +@interface DoricListNode : DoricSuperNode @end \ No newline at end of file diff --git a/iOS/Pod/Classes/Shader/DoricListNode.m b/iOS/Pod/Classes/Shader/DoricListNode.m index f0b6cb29..9a83e628 100644 --- a/iOS/Pod/Classes/Shader/DoricListNode.m +++ b/iOS/Pod/Classes/Shader/DoricListNode.m @@ -22,8 +22,16 @@ #import "DoricExtensions.h" #import "DoricListItemNode.h" +@interface DoricTableViewCell : UITableViewCell +@property(nonatomic, strong) DoricListItemNode *doricListItemNode; +@end + +@implementation DoricTableViewCell +@end + @interface DoricListNode () -@property(nonatomic, strong) NSMutableDictionary *tempNodes; +@property(nonatomic, strong) NSMutableDictionary *itemViewIds; +@property(nonatomic, strong) NSMutableDictionary *itemHeights; @property(nonatomic, assign) NSUInteger itemCount; @property(nonatomic, assign) NSUInteger batchCount; @end @@ -31,7 +39,8 @@ @interface DoricListNode () @implementation DoricListNode - (instancetype)initWithContext:(DoricContext *)doricContext { if (self = [super initWithContext:doricContext]) { - _tempNodes = [NSMutableDictionary new]; + _itemViewIds = [NSMutableDictionary new]; + _itemHeights = [NSMutableDictionary new]; _batchCount = 15; } return self; @@ -41,6 +50,7 @@ - (UITableView *)build { return [[UITableView new] also:^(UITableView *it) { it.dataSource = self; it.delegate = self; + it.separatorStyle = UITableViewCellSeparatorStyleNone; }]; } @@ -48,7 +58,7 @@ - (void)blendView:(UITableView *)view forPropName:(NSString *)name propValue:(id if ([@"itemCount" isEqualToString:name]) { self.itemCount = [prop unsignedIntegerValue]; } else if ([@"renderItem" isEqualToString:name]) { - [self.tempNodes removeAllObjects]; + [self.itemViewIds removeAllObjects]; [self clearSubModel]; } else if ([@"batchCount" isEqualToString:name]) { self.batchCount = [prop unsignedIntegerValue]; @@ -59,7 +69,6 @@ - (void)blendView:(UITableView *)view forPropName:(NSString *)name propValue:(id - (void)blend:(NSDictionary *)props { [super blend:props]; - [self.view reloadData]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { @@ -72,25 +81,35 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N NSDictionary *props = model[@"props"]; NSString *reuseId = props[@"identifier"]; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId]; + DoricTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId]; if (!cell) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId]; + cell = [[DoricTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId]; + DoricListItemNode *listItemNode = [[DoricListItemNode alloc] initWithContext:self.doricContext]; + [listItemNode initWithSuperNode:self]; + cell.doricListItemNode = listItemNode; + [cell.contentView addSubview:listItemNode.view]; } - DoricListItemNode *node = self.tempNodes[@(position)]; - node.view = cell; + DoricListItemNode *node = cell.doricListItemNode; + node.viewId = model[@"id"]; [node blend:props]; + CGSize size = [node.view sizeThatFits:CGSizeMake(cell.width, cell.height)]; + [self callItem:position height:size.height]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSUInteger position = (NSUInteger) indexPath.row; - NSDictionary *model = [self itemModelAt:position]; + NSNumber *heightNumber = self.itemHeights[@(position)]; + if (heightNumber) { + return [heightNumber floatValue]; + } else { + return 44.f; + } - return 60; } - (NSDictionary *)itemModelAt:(NSUInteger)position { - NSString *viewId = self.tempNodes[@(position)].viewId; + NSString *viewId = self.itemViewIds[@(position)]; if (viewId && viewId.length > 0) { return [self subModelOf:viewId]; } else { @@ -101,13 +120,30 @@ - (NSDictionary *)itemModelAt:(NSUInteger)position { NSString *thisViewId = obj[@"id"]; [self setSubModel:obj in:thisViewId]; NSUInteger pos = position + idx; - DoricListItemNode *node = [[DoricListItemNode alloc] initWithContext:self.doricContext]; - node.viewId = thisViewId; - [node initWithSuperNode:self]; - self.tempNodes[@(pos)] = node; + self.itemViewIds[@(pos)] = thisViewId; }]; return array[0]; } } +- (void)blendSubNode:(NSDictionary *)subModel { + NSString *viewId = subModel[@"id"]; + [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]; + [self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; + } + }]; +} + +- (void)callItem:(NSUInteger)position height:(CGFloat)height { + NSNumber *old = self.itemHeights[@(position)]; + if (old && old.floatValue == height) { + return; + } + self.itemHeights[@(position)] = @(height); + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:position inSection:0]; + [self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; +} @end