This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Doric/iOS/Pod/Classes/Shader/DoricCollectionNode.m

142 lines
4.9 KiB
Mathematica
Raw Normal View History

2019-11-28 13:59:55 +08:00
//
// Created by pengfei.zhou on 2019/11/28.
//
#import "DoricCollectionNode.h"
#import "DoricCollectionItemNode.h"
#import "DoricExtensions.h"
2019-11-28 14:02:11 +08:00
#import <JavaScriptCore/JavaScriptCore.h>
2019-11-28 13:59:55 +08:00
@interface DoricCollectionViewCell : UICollectionViewCell
@property(nonatomic, strong) DoricCollectionItemNode *viewNode;
@end
@implementation DoricCollectionViewCell
@end
@interface DoricCollectionView : UICollectionView
@end
@implementation DoricCollectionView
- (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 reloadData];
}
@end
@interface DoricCollectionNode () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSString *> *itemViewIds;
@property(nonatomic, assign) NSUInteger itemCount;
@property(nonatomic, assign) NSUInteger batchCount;
@end
@implementation DoricCollectionNode
- (instancetype)initWithContext:(DoricContext *)doricContext {
if (self = [super initWithContext:doricContext]) {
_itemViewIds = [NSMutableDictionary new];
_batchCount = 15;
}
return self;
}
- (UICollectionView *)build {
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
return [[[DoricCollectionView alloc] initWithFrame:CGRectZero
collectionViewLayout:flowLayout]
also:^(UICollectionView *it) {
it.backgroundColor = [UIColor whiteColor];
it.pagingEnabled = YES;
it.delegate = self;
it.dataSource = self;
[it registerClass:[DoricCollectionViewCell class] forCellWithReuseIdentifier:@"doricCell"];
}];
}
2019-11-28 14:02:11 +08:00
- (void)blendView:(UICollectionView *)view forPropName:(NSString *)name propValue:(id)prop {
if ([@"itemCount" isEqualToString:name]) {
self.itemCount = [prop unsignedIntegerValue];
[self.view reloadData];
} else if ([@"renderPage" isEqualToString:name]) {
[self.itemViewIds removeAllObjects];
[self clearSubModel];
[self.view reloadData];
} else if ([@"batchCount" isEqualToString:name]) {
self.batchCount = [prop unsignedIntegerValue];
} else {
[super blendView:view forPropName:name propValue:prop];
}
}
- (NSDictionary *)itemModelAt:(NSUInteger)position {
NSString *viewId = self.itemViewIds[@(position)];
if (viewId && viewId.length > 0) {
return [self subModelOf:viewId];
} else {
DoricAsyncResult *result = [self callJSResponse:@"renderBunchedItems", @(position), @(self.batchCount), nil];
JSValue *models = [result waitUntilResult];
NSArray *array = [models toArray];
[array enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
NSString *thisViewId = obj[@"id"];
[self setSubModel:obj in:thisViewId];
NSUInteger pos = position + idx;
self.itemViewIds[@(pos)] = thisViewId;
}];
return array[0];
}
}
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
__block DoricViewNode *ret = nil;
[self.doricContext.driver ensureSyncInMainQueue:^{
for (UICollectionViewCell *collectionViewCell in self.view.visibleCells) {
if ([collectionViewCell isKindOfClass:[DoricCollectionViewCell class]]) {
DoricCollectionItemNode *node = ((DoricCollectionViewCell *) collectionViewCell).viewNode;
if ([viewId isEqualToString:node.viewId]) {
ret = node;
break;
}
}
}
}];
return ret;
}
- (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]];
}];
}
}];
}
2019-11-28 13:59:55 +08:00
@end