如何以确定的顺序添加自定义React Native子视图

时间:2019-09-03 15:48:09

标签: ios objective-c react-native react-native-ios

我有几个自定义的反应本机视图,并希望像这样将它们组织在树中:

<Parent ... >
  <ChildA ... >
    <ChildB .. >
      <ChildC ... />
    </ChildB>
  </ChildA>
</Parent>

在渲染这些组件时,我需要实现自定义逻辑,并且本质上需要让每个子对象都包含对Parent的引用(就像在React中转发引用一样)。

所以我的想法是重写每个子组件的addSubview方法,并创建名为addParent的方法,以便以后调用。

// Child.m

- (void)addSubview:(UIView *)view {
  if ([view isKindOfClass:[Child class]]) {
    [_children addObject:(Child *)view]
  }
}

- (void)addParent:(Parent *)parentView{
  _parent = parentView;
  for (Child *c in _children) {
    [c addParent:parentView];
  }
}

这样,我可以存储对每个视图的子级列表的引用,然后覆盖父级的addSubview并将父级传递给树:

// Parent.m

- (void)addSubview:(UIView *)view {
  if ([view isKindOfClass:[Child class]]) {
    [((Child *)view) addParent:self];
  }
}

这仅在addingSubviews的顺序如下时起作用:

  

ChildC-> ChildB-> ChildA->父级。

这是我对React树的期望,这就是它在Android中的工作方式(尽管ViewGroupManagers的策略略有不同),但在iOS中似乎没有确定的顺序。

据我所知的原因在 RCTUIManager.m 中。_dispatchChildrenDidChangeEvents这里的tags数组并非总是按预期的顺序排列,因为它是针对阴影视图的标签(是HashTable)

- (void)_dispatchChildrenDidChangeEvents
{
  if (_shadowViewsWithUpdatedChildren.count == 0) {
    return;
  }

  NSHashTable<RCTShadowView *> *shadowViews = _shadowViewsWithUpdatedChildren;
  _shadowViewsWithUpdatedChildren = [NSHashTable weakObjectsHashTable];

  NSMutableArray *tags = [NSMutableArray arrayWithCapacity:shadowViews.count];

  for (RCTShadowView *shadowView in shadowViews) {
    [shadowView didUpdateReactSubviews];
    [tags addObject:shadowView.reactTag];
  }

  [self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
    for (NSNumber *tag in tags) {
      UIView<RCTComponent> *view = viewRegistry[tag];
      [view didUpdateReactSubviews];
    }
  }];
}

那么这是React Native或预期行为的问题吗?正确的方法是什么?我对React Native不太熟悉,对iOS开发也绝对不熟悉。

也许我应该重写另一种方法或监听一个事件。

0 个答案:

没有答案