From 4eeebf61187bffc2079516bc29c551ce7323654f Mon Sep 17 00:00:00 2001 From: osborn Date: Tue, 3 Jan 2023 16:42:52 +0800 Subject: [PATCH] Feature/fix npe exception (#566) * android: add exception catch for list flowlayout scroller type * iOS: add exception catch for list flowlayout scroller type --- .../doric/shader/flowlayout/FlowAdapter.java | 63 ++++++++-------- .../horizontallist/HorizontalListAdapter.java | 32 ++++---- .../pub/doric/shader/list/ListAdapter.java | 32 ++++---- .../pub/doric/shader/slider/SlideAdapter.java | 21 +++--- .../Pod/Classes/Shader/DoricFlowLayoutNode.m | 75 ++++++++++--------- .../Classes/Shader/DoricHorizontalListNode.m | 71 ++++++++++-------- doric-iOS/Pod/Classes/Shader/DoricListNode.m | 69 +++++++++-------- .../Pod/Classes/Shader/DoricSliderNode.m | 43 ++++++----- 8 files changed, 220 insertions(+), 186 deletions(-) diff --git a/doric-android/doric/src/main/java/pub/doric/shader/flowlayout/FlowAdapter.java b/doric-android/doric/src/main/java/pub/doric/shader/flowlayout/FlowAdapter.java index b9500423..a10f3203 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/flowlayout/FlowAdapter.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/flowlayout/FlowAdapter.java @@ -20,16 +20,15 @@ import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.StaggeredGridLayoutManager; - import com.github.pengfeizhou.jscore.JSArray; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSNull; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; import pub.doric.async.AsyncResult; import pub.doric.shader.ViewNode; @@ -62,33 +61,37 @@ class FlowAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(@NonNull DoricViewHolder holder, int position) { - JSValue jsValue = getItemModel(position); - boolean fullSpan = this.loadMore && position >= this.itemCount; - if (jsValue != null && jsValue.isObject()) { - JSObject jsObject = jsValue.asObject(); - holder.flowLayoutItemNode.setId(jsObject.getProperty("id").asString().value()); - JSObject props = jsObject.getProperty("props").asObject(); - holder.flowLayoutItemNode.reset(); - holder.flowLayoutItemNode.blend(props); - JSValue fullSpanValue = props.getProperty("fullSpan"); - if (fullSpanValue.isBoolean()) { - fullSpan = fullSpanValue.asBoolean().value(); + try { + JSValue jsValue = getItemModel(position); + boolean fullSpan = this.loadMore && position >= this.itemCount; + if (jsValue != null && jsValue.isObject()) { + JSObject jsObject = jsValue.asObject(); + holder.flowLayoutItemNode.setId(jsObject.getProperty("id").asString().value()); + JSObject props = jsObject.getProperty("props").asObject(); + holder.flowLayoutItemNode.reset(); + holder.flowLayoutItemNode.blend(props); + JSValue fullSpanValue = props.getProperty("fullSpan"); + if (fullSpanValue.isBoolean()) { + fullSpan = fullSpanValue.asBoolean().value(); + } } - } - if (holder.itemView.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams) { - ((StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams()).setFullSpan(fullSpan); - } else if (fullSpan) { - StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - holder.itemView.getLayoutParams().height - ); - layoutParams.setFullSpan(true); - holder.itemView.setLayoutParams(layoutParams); - } - if (this.loadMore - && position >= this.itemCount - && !TextUtils.isEmpty(this.flowLayoutNode.onLoadMoreFuncId)) { - callLoadMore(); + if (holder.itemView.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams) { + ((StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams()).setFullSpan(fullSpan); + } else if (fullSpan) { + StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + holder.itemView.getLayoutParams().height + ); + layoutParams.setFullSpan(true); + holder.itemView.setLayoutParams(layoutParams); + } + if (this.loadMore + && position >= this.itemCount + && !TextUtils.isEmpty(this.flowLayoutNode.onLoadMoreFuncId)) { + callLoadMore(); + } + } catch (Exception e) { + flowLayoutNode.getDoricContext().getDriver().getRegistry().onException(flowLayoutNode.getDoricContext(), e); } } diff --git a/doric-android/doric/src/main/java/pub/doric/shader/horizontallist/HorizontalListAdapter.java b/doric-android/doric/src/main/java/pub/doric/shader/horizontallist/HorizontalListAdapter.java index 7a7432ec..4cc192ce 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/horizontallist/HorizontalListAdapter.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/horizontallist/HorizontalListAdapter.java @@ -21,15 +21,14 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - import com.github.pengfeizhou.jscore.JSArray; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSNull; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import pub.doric.async.AsyncResult; import pub.doric.shader.ViewNode; @@ -49,6 +48,7 @@ class HorizontalListAdapter extends RecyclerView.Adapter= this.itemCount - && !TextUtils.isEmpty(this.horizontalListNode.onLoadMoreFuncId)) { - callLoadMore(); + try { + JSValue jsValue = getItemModel(position); + if (jsValue != null && jsValue.isObject()) { + JSObject jsObject = jsValue.asObject(); + holder.horizontalListItemNode.setId(jsObject.getProperty("id").asString().value()); + holder.horizontalListItemNode.reset(); + holder.horizontalListItemNode.blend(jsObject.getProperty("props").asObject()); + } + if (this.loadMore + && position >= this.itemCount + && !TextUtils.isEmpty(this.horizontalListNode.onLoadMoreFuncId)) { + callLoadMore(); + } + } catch (Exception e) { + horizontalListNode.getDoricContext().getDriver().getRegistry().onException(horizontalListNode.getDoricContext(), e); } } diff --git a/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java b/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java index 8a95ca5d..342e090a 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java @@ -21,15 +21,14 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - import com.github.pengfeizhou.jscore.JSArray; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSNull; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import pub.doric.async.AsyncResult; import pub.doric.shader.ViewNode; @@ -49,6 +48,7 @@ class ListAdapter extends RecyclerView.Adapter { int itemCount = 0; int loadAnchor = -1; boolean loadMore = false; + @NonNull @Override public DoricViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -59,17 +59,21 @@ class ListAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(@NonNull DoricViewHolder holder, int position) { - JSValue jsValue = getItemModel(position); - if (jsValue != null && jsValue.isObject()) { - JSObject jsObject = jsValue.asObject(); - holder.listItemNode.setId(jsObject.getProperty("id").asString().value()); - holder.listItemNode.reset(); - holder.listItemNode.blend(jsObject.getProperty("props").asObject()); - } - if (this.loadMore - && position >= this.itemCount - && !TextUtils.isEmpty(this.listNode.onLoadMoreFuncId)) { - callLoadMore(); + try { + JSValue jsValue = getItemModel(position); + if (jsValue != null && jsValue.isObject()) { + JSObject jsObject = jsValue.asObject(); + holder.listItemNode.setId(jsObject.getProperty("id").asString().value()); + holder.listItemNode.reset(); + holder.listItemNode.blend(jsObject.getProperty("props").asObject()); + } + if (this.loadMore + && position >= this.itemCount + && !TextUtils.isEmpty(this.listNode.onLoadMoreFuncId)) { + callLoadMore(); + } + } catch (Exception e) { + listNode.getDoricContext().getDriver().getRegistry().onException(listNode.getDoricContext(), e); } } diff --git a/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java b/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java index 8d8643a7..88ec4f08 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java @@ -20,15 +20,14 @@ import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - import com.github.pengfeizhou.jscore.JSArray; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSNull; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import pub.doric.async.AsyncResult; import pub.doric.shader.ViewNode; @@ -61,12 +60,16 @@ class SlideAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(@NonNull DoricViewHolder holder, int position) { - JSValue jsValue = getItemModel(position); - if (jsValue != null && jsValue.isObject()) { - JSObject jsObject = jsValue.asObject(); - holder.slideItemNode.setId(jsObject.getProperty("id").asString().value()); - holder.slideItemNode.reset(); - holder.slideItemNode.blend(jsObject.getProperty("props").asObject()); + try { + JSValue jsValue = getItemModel(position); + if (jsValue != null && jsValue.isObject()) { + JSObject jsObject = jsValue.asObject(); + holder.slideItemNode.setId(jsObject.getProperty("id").asString().value()); + holder.slideItemNode.reset(); + holder.slideItemNode.blend(jsObject.getProperty("props").asObject()); + } + } catch (Exception e) { + sliderNode.getDoricContext().getDriver().getRegistry().onException(sliderNode.getDoricContext(), e); } } diff --git a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m index f85b285e..cd48170c 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m @@ -399,11 +399,11 @@ - (void)blendSubNode:(NSDictionary *)subModel { NSString *viewId = subModel[@"id"]; DoricViewNode *viewNode = [self subNodeWithViewId:viewId]; BOOL skipReload = NO; - + NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy]; [self recursiveMixin:subModel to:model]; [self setSubModel:model in:viewId]; - + if (viewNode) { CGSize originSize = viewNode.view.frame.size; [viewNode blend:subModel[@"props"]]; @@ -413,7 +413,7 @@ - (void)blendSubNode:(NSDictionary *)subModel { skipReload = YES; } } - + if (skipReload) { return; } @@ -459,41 +459,46 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSe } - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - NSUInteger position = (NSUInteger) indexPath.row; - NSDictionary *model = [self itemModelAt:position]; - NSDictionary *props = model[@"props"]; - NSString *identifier = props[@"identifier"] ?: @"doricCell"; - if (self.loadMore - && position >= self.itemCount - && self.onLoadMoreFuncId) { - identifier = @"doricLoadMoreCell"; - [self callLoadMore]; - } - [collectionView registerClass:[DoricFlowLayoutViewCell class] forCellWithReuseIdentifier:identifier]; - DoricFlowLayoutViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; - if (!cell.viewNode) { - DoricFlowLayoutItemNode *itemNode = (DoricFlowLayoutItemNode *) [DoricViewNode create:self.doricContext withType:@"FlowLayoutItem"]; - [itemNode initWithSuperNode:self]; - cell.viewNode = itemNode; - [cell.contentView addSubview:itemNode.view]; - } else { - [cell.viewNode reset]; - } + @try { + NSUInteger position = (NSUInteger) indexPath.row; + NSDictionary *model = [self itemModelAt:position]; + NSDictionary *props = model[@"props"]; + NSString *identifier = props[@"identifier"] ?: @"doricCell"; + if (self.loadMore + && position >= self.itemCount + && self.onLoadMoreFuncId) { + identifier = @"doricLoadMoreCell"; + [self callLoadMore]; + } + [collectionView registerClass:[DoricFlowLayoutViewCell class] forCellWithReuseIdentifier:identifier]; + DoricFlowLayoutViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; + if (!cell.viewNode) { + DoricFlowLayoutItemNode *itemNode = (DoricFlowLayoutItemNode *) [DoricViewNode create:self.doricContext withType:@"FlowLayoutItem"]; + [itemNode initWithSuperNode:self]; + cell.viewNode = itemNode; + [cell.contentView addSubview:itemNode.view]; + } else { + [cell.viewNode reset]; + } - DoricFlowLayoutItemNode *node = cell.viewNode; - node.viewId = model[@"id"]; - [node blend:props]; + DoricFlowLayoutItemNode *node = cell.viewNode; + node.viewId = model[@"id"]; + [node blend:props]; - BOOL fullSpan = self.loadMore && position >= self.itemCount; - if (props[@"fullSpan"]) { - fullSpan = [props[@"fullSpan"] boolValue]; + BOOL fullSpan = self.loadMore && position >= self.itemCount; + if (props[@"fullSpan"]) { + fullSpan = [props[@"fullSpan"] boolValue]; + } + CGFloat width = fullSpan ? collectionView.width : (collectionView.width - (self.columnCount - 1) * self.columnSpace) / self.columnCount; + CGFloat height = node.view.doricLayout.heightSpec == DoricLayoutFit ? CGFLOAT_MAX : collectionView.height; + [node.view.doricLayout apply:CGSizeMake(width, height)]; + [node requestLayout]; + [self callItem:position size:node.view.frame.size]; + return cell; + } @catch (NSException *exception) { + [self.doricContext.driver.registry onException:exception inContext:self.doricContext]; + return nil; } - CGFloat width = fullSpan ? collectionView.width : (collectionView.width - (self.columnCount - 1) * self.columnSpace) / self.columnCount; - CGFloat height = node.view.doricLayout.heightSpec == DoricLayoutFit ? CGFLOAT_MAX : collectionView.height; - [node.view.doricLayout apply:CGSizeMake(width, height)]; - [node requestLayout]; - [self callItem:position size:node.view.frame.size]; - return cell; } - (NSIndexPath *)collectionView:(UICollectionView *)collectionView targetIndexPathForMoveFromItemAtIndexPath:(NSIndexPath *)currentIndexPath toProposedIndexPath:(NSIndexPath *)proposedIndexPath { diff --git a/doric-iOS/Pod/Classes/Shader/DoricHorizontalListNode.m b/doric-iOS/Pod/Classes/Shader/DoricHorizontalListNode.m index 2c3c5c66..3a69b86f 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricHorizontalListNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricHorizontalListNode.m @@ -240,37 +240,42 @@ - (void)callLoadMore { } - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - NSUInteger position = (NSUInteger) indexPath.row; - NSDictionary *model = [self itemModelAt:position]; - NSDictionary *props = model[@"props"]; - NSString *identifier = props[@"identifier"] ?: @"doricCell"; - self.itemActions[@(position)] = props[@"actions"]; - if (self.loadMore - && position >= self.rowCount - 1 - && self.onLoadMoreFuncId) { - identifier = @"doricLoadMoreCell"; - [self callLoadMore]; + @try { + NSUInteger position = (NSUInteger) indexPath.row; + NSDictionary *model = [self itemModelAt:position]; + NSDictionary *props = model[@"props"]; + NSString *identifier = props[@"identifier"] ?: @"doricCell"; + self.itemActions[@(position)] = props[@"actions"]; + if (self.loadMore + && position >= self.rowCount - 1 + && self.onLoadMoreFuncId) { + identifier = @"doricLoadMoreCell"; + [self callLoadMore]; + } + [collectionView registerClass:[DoricHorizontalTableViewCell class] forCellWithReuseIdentifier:identifier]; + DoricHorizontalTableViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; + if (!cell.doricHorizontalListItemNode) { + DoricHorizontalListItemNode *itemNode = (DoricHorizontalListItemNode *) [DoricViewNode create:self.doricContext withType:@"HorizontalListItem"]; + [itemNode initWithSuperNode:self]; + cell.doricHorizontalListItemNode = itemNode; + cell.backgroundColor = [UIColor clearColor]; + itemNode.view.height = collectionView.height; + [cell.contentView addSubview:itemNode.view]; + } else { + [cell.doricHorizontalListItemNode reset]; + } + DoricHorizontalListItemNode *node = cell.doricHorizontalListItemNode; + node.viewId = model[@"id"]; + [node blend:props]; + CGFloat width = node.view.doricLayout.widthSpec == DoricLayoutFit ? CGFLOAT_MAX : collectionView.width; + [node.view.doricLayout apply:CGSizeMake(width, collectionView.height)]; + [node requestLayout]; + [self callItem:position width:node.view.width]; + return cell; + } @catch (NSException *exception) { + [self.doricContext.driver.registry onException:exception inContext:self.doricContext]; + return nil; } - [collectionView registerClass:[DoricHorizontalTableViewCell class] forCellWithReuseIdentifier:identifier]; - DoricHorizontalTableViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; - if (!cell.doricHorizontalListItemNode) { - DoricHorizontalListItemNode *itemNode = (DoricHorizontalListItemNode *) [DoricViewNode create:self.doricContext withType:@"HorizontalListItem"]; - [itemNode initWithSuperNode:self]; - cell.doricHorizontalListItemNode = itemNode; - cell.backgroundColor = [UIColor clearColor]; - itemNode.view.height = collectionView.height; - [cell.contentView addSubview:itemNode.view]; - } else { - [cell.doricHorizontalListItemNode reset]; - } - DoricHorizontalListItemNode *node = cell.doricHorizontalListItemNode; - node.viewId = model[@"id"]; - [node blend:props]; - CGFloat width = node.view.doricLayout.widthSpec == DoricLayoutFit ? CGFLOAT_MAX : collectionView.width; - [node.view.doricLayout apply:CGSizeMake(width, collectionView.height)]; - [node requestLayout]; - [self callItem:position width:node.view.width]; - return cell; } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { @@ -337,11 +342,11 @@ - (void)blendSubNode:(NSDictionary *)subModel { NSString *viewId = subModel[@"id"]; DoricViewNode *viewNode = [self subNodeWithViewId:viewId]; BOOL skipReload = NO; - + NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy]; [self recursiveMixin:subModel to:model]; [self setSubModel:model in:viewId]; - + if (viewNode) { CGSize originSize = viewNode.view.frame.size; [viewNode blend:subModel[@"props"]]; @@ -351,7 +356,7 @@ - (void)blendSubNode:(NSDictionary *)subModel { skipReload = YES; } } - + if (skipReload) { return; } diff --git a/doric-iOS/Pod/Classes/Shader/DoricListNode.m b/doric-iOS/Pod/Classes/Shader/DoricListNode.m index cbd11b6c..69c3f68c 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricListNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricListNode.m @@ -242,37 +242,42 @@ - (void)callLoadMore { } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSUInteger position = (NSUInteger) indexPath.row; - NSDictionary *model = [self itemModelAt:position]; - NSDictionary *props = model[@"props"]; - NSString *reuseId = props[@"identifier"]; - self.itemActions[@(position)] = props[@"actions"]; - if (self.loadMore - && position >= self.rowCount - 1 - && self.onLoadMoreFuncId) { - reuseId = @"doricLoadMoreCell"; - [self callLoadMore]; + @try { + NSUInteger position = (NSUInteger) indexPath.row; + NSDictionary *model = [self itemModelAt:position]; + NSDictionary *props = model[@"props"]; + NSString *reuseId = props[@"identifier"]; + self.itemActions[@(position)] = props[@"actions"]; + if (self.loadMore + && position >= self.rowCount - 1 + && self.onLoadMoreFuncId) { + reuseId = @"doricLoadMoreCell"; + [self callLoadMore]; + } + DoricTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId ?: @"doricCell"]; + if (!cell) { + cell = [[DoricTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId ?: @"doricCell"]; + DoricListItemNode *listItemNode = (DoricListItemNode *) [DoricViewNode create:self.doricContext withType:@"ListItem"]; + [listItemNode initWithSuperNode:self]; + cell.doricListItemNode = listItemNode; + cell.backgroundColor = [UIColor clearColor]; + listItemNode.view.width = tableView.width; + [cell.contentView addSubview:listItemNode.view]; + } else { + [cell.doricListItemNode reset]; + } + DoricListItemNode *node = cell.doricListItemNode; + node.viewId = model[@"id"]; + [node blend:props]; + CGFloat height = node.view.doricLayout.heightSpec == DoricLayoutFit ? CGFLOAT_MAX : tableView.height; + [node.view.doricLayout apply:CGSizeMake(tableView.width, height)]; + [node requestLayout]; + [self callItem:position height:node.view.height]; + return cell; + } @catch (NSException *exception) { + [self.doricContext.driver.registry onException:exception inContext:self.doricContext]; + return nil; } - DoricTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId ?: @"doricCell"]; - if (!cell) { - cell = [[DoricTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId ?: @"doricCell"]; - DoricListItemNode *listItemNode = (DoricListItemNode *) [DoricViewNode create:self.doricContext withType:@"ListItem"]; - [listItemNode initWithSuperNode:self]; - cell.doricListItemNode = listItemNode; - cell.backgroundColor = [UIColor clearColor]; - listItemNode.view.width = tableView.width; - [cell.contentView addSubview:listItemNode.view]; - } else { - [cell.doricListItemNode reset]; - } - DoricListItemNode *node = cell.doricListItemNode; - node.viewId = model[@"id"]; - [node blend:props]; - CGFloat height = node.view.doricLayout.heightSpec == DoricLayoutFit ? CGFLOAT_MAX : tableView.height; - [node.view.doricLayout apply:CGSizeMake(tableView.width, height)]; - [node requestLayout]; - [self callItem:position height:node.view.height]; - return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -381,11 +386,11 @@ - (void)blendSubNode:(NSDictionary *)subModel { NSString *viewId = subModel[@"id"]; DoricViewNode *viewNode = [self subNodeWithViewId:viewId]; BOOL skipReload = NO; - + NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy]; [self recursiveMixin:subModel to:model]; [self setSubModel:model in:viewId]; - + if (viewNode) { CGSize originSize = viewNode.view.frame.size; [viewNode blend:subModel[@"props"]]; diff --git a/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m b/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m index 4f56ef0b..4530755f 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m @@ -177,24 +177,29 @@ - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectio } - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - NSUInteger position = (NSUInteger) indexPath.row; - NSDictionary *model = [self itemModelAt:position]; - NSDictionary *props = model[@"props"]; - DoricSliderViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"doricCell" forIndexPath:indexPath]; - if (!cell.doricSlideItemNode) { - DoricSlideItemNode *slideItemNode = (DoricSlideItemNode *) [DoricViewNode create:self.doricContext withType:@"SlideItem"]; - [slideItemNode initWithSuperNode:self]; - cell.doricSlideItemNode = slideItemNode; - [cell.contentView addSubview:slideItemNode.view]; - } else { - [cell.doricSlideItemNode reset]; + @try { + NSUInteger position = (NSUInteger) indexPath.row; + NSDictionary *model = [self itemModelAt:position]; + NSDictionary *props = model[@"props"]; + DoricSliderViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"doricCell" forIndexPath:indexPath]; + if (!cell.doricSlideItemNode) { + DoricSlideItemNode *slideItemNode = (DoricSlideItemNode *) [DoricViewNode create:self.doricContext withType:@"SlideItem"]; + [slideItemNode initWithSuperNode:self]; + cell.doricSlideItemNode = slideItemNode; + [cell.contentView addSubview:slideItemNode.view]; + } else { + [cell.doricSlideItemNode reset]; + } + DoricSlideItemNode *node = cell.doricSlideItemNode; + node.viewId = model[@"id"]; + [node blend:props]; + [node.view.doricLayout apply:CGSizeMake(collectionView.width, collectionView.height)]; + [node requestLayout]; + return cell; + } @catch (NSException *exception) { + [self.doricContext.driver.registry onException:exception inContext:self.doricContext]; + return nil; } - DoricSlideItemNode *node = cell.doricSlideItemNode; - node.viewId = model[@"id"]; - [node blend:props]; - [node.view.doricLayout apply:CGSizeMake(collectionView.width, collectionView.height)]; - [node requestLayout]; - return cell; } - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { @@ -253,11 +258,11 @@ - (void)blendSubNode:(NSDictionary *)subModel { NSString *viewId = subModel[@"id"]; DoricViewNode *viewNode = [self subNodeWithViewId:viewId]; BOOL skipReload = NO; - + NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy]; [self recursiveMixin:subModel to:model]; [self setSubModel:model in:viewId]; - + if (viewNode) { CGSize originSize = viewNode.view.frame.size; [viewNode blend:subModel[@"props"]];