我有几个自定义的反应本机视图,并希望像这样将它们组织在树中:
<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开发也绝对不熟悉。
也许我应该重写另一种方法或监听一个事件。