Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
changedProps:(folly::dynamic)props
componentDescriptor:(const facebook::react::ComponentDescriptor &)componentDescriptor;

- (void)measureAsyncOnUI:(ReactTag)reactTag
rootView:(UIView *)rootView
callback:(const std::function<void(folly::dynamic)> &)callback;
@end

NS_ASSUME_NONNULL_END
27 changes: 27 additions & 0 deletions packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,31 @@ - (void)synchronouslyDispatchAccessbilityEventOnUIThread:(ReactTag)reactTag even
}
}

- (void)measureAsyncOnUI:(ReactTag)reactTag
rootView:(UIView *)rootView
callback:(const std::function<void(folly::dynamic)> &)callback
{
RCTAssertMainQueue();

UIView<RCTComponentViewProtocol> *view = [self->_componentViewRegistry findComponentViewWithTag:reactTag];
if (!view) {
RCTLogWarn(@"measure cannot find view with tag #%ld", (long)reactTag);
callback(folly::dynamic::array(0, 0, 0, 0, 0, 0));
return;
}

// By convention, all coordinates, whether they be touch coordinates, or
// measurement coordinates are with respect to the root view.
CGRect frame = view.frame;
CGRect globalBounds = [view convertRect:view.bounds toView:rootView];

callback(folly::dynamic::array(
frame.origin.x,
frame.origin.y,
globalBounds.size.width,
globalBounds.size.height,
globalBounds.origin.x,
globalBounds.origin.y));
}

@end
25 changes: 18 additions & 7 deletions packages/react-native/React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <React/RCTConstants.h>
#import <React/RCTFabricSurface.h>
#import <React/RCTI18nUtil.h>
#import <React/RCTLog.h>
#import <React/RCTMountingManager.h>
#import <React/RCTMountingManagerDelegate.h>
#import <React/RCTScheduler.h>
Expand Down Expand Up @@ -348,13 +349,23 @@ - (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer
}
}

- (void)schedulerMeasure:(const facebook::react::ShadowView &)shadowView jsCallback:(std::function<void (folly::dynamic)>)jsCallback {
// TODO: do we need to implement this on iOS? It seems to _just work_
// dispatch_async(dispatch_get_main_queue(), ^{
// ReactTag tag = shadowView.tag;
// UIView<RCTComponentViewProtocol> *componentView =
// [self->_mountingManager.componentViewRegistry findComponentViewWithTag:tag];
// });
- (void)schedulerMeasure:(const facebook::react::ShadowView &)shadowView
jsCallback:(std::function<void(folly::dynamic)>)jsCallback
{
ReactTag tag = shadowView.tag;
SurfaceId surfaceId = shadowView.surfaceId;

std::function<void(folly::dynamic)> callbackCopy = jsCallback;
RCTExecuteOnMainQueue(^{
RCTFabricSurface *surface = [self surfaceForRootTag:surfaceId];
UIView *rootView = surface.view;
if (!rootView) {
RCTLogWarn(@"measure cannot find root view for surface #%d", surfaceId);
callbackCopy(folly::dynamic::array(0, 0, 0, 0, 0, 0));
return;
}
[self->_mountingManager measureAsyncOnUI:tag rootView:rootView callback:callbackCopy];
});
}

#pragma mark - RCTMountingManagerDelegate
Expand Down
Loading