Closed
Description
Environment
Description
I am using the shadow view to locate the absolute coordinates of a component in the screen.
with 0.53.0 everything was fine, I was overriding applyLayoutNode and doing :
- (void)applyLayoutNode:(YGNodeRef)node
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition
{
[_bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
RCTMyView *view = (RCTMyView*)viewRegistry[self.reactTag];
if ([view isKindOfClass:[RCTMyView class]]) {
CGRect rect = CGRectMake(absolutePosition.x+YGNodeLayoutGetLeft(node), absolutePosition.y+YGNodeLayoutGetTop(node), YGNodeLayoutGetWidth(node), YGNodeLayoutGetHeight(node));
[view updateComponent:rect];
} else {
RCTLogError(@"Cannot update button: %@ (tag #%@) is not RCTMyView", view, self.reactTag);
}
}];
[super applyLayoutNode:node viewsWithNewFrame:viewsWithNewFrame
absolutePosition:absolutePosition];
}
This function was only invoked when the layout requested a change, e.g screen rotation
with the next version, the interface has been broken in iOS only(still the same in android), so my code didn't compile anymore, which is something odd, since it's a public interface and obliged me to change my component code depending on the version. RCTView interface is not broken, otherwise most 3rd party components will not compile anymore.
With 0.55.4, I need to overwrite layoutWithMetrics :
- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics
layoutContext:(RCTLayoutContext)layoutContext {
[_bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
RCTMyView *view = (RCTMyView*)viewRegistry[self.reactTag];
if ([view isKindOfClass:[RCTMyView class]]) {
// RN framework always adds 2 subviews to the rootView, the 3 anchored to the origin (0,0).
// subv2 will be the parent of the view we declare in render()
// --------------- rootView
// --------------- subv1
// --------------- subv2
CGRect rect = layoutMetrics.frame;
RCTShadowView* v = self.superview;
while (v) {
rect.origin.x += v.layoutMetrics.frame.origin.x;
rect.origin.y += v.layoutMetrics.frame.origin.y;
v = v.superview;
}
[view updateComponent:rect];
} else {
RCTLogError(@"Cannot update button: %@ (tag #%@) is not RCTMyView", view, self.reactTag);
}
}];
[super layoutWithMetrics:layoutMetrics layoutContext:layoutContext];
}
This new function has 3 problems:
- it is periodically invoked, even if nothing has changed on screen
- it is not possible to get the absolute coordinates using the parameters layoutMetrics or layoutContext, without having to loop as I do here. Remember in 0.53.0 I was having the absolute position of the parent node...
- is there any plan to break this public interface again in the future? this will not be a viable solution for my client who will need a new release everytime the interface is changed
It would be nice to have a react native core developper having a look at this.