From 8b4ed9490c0a52ab08e1185eaae9173028e10cba Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 24 Sep 2017 22:57:28 -0700 Subject: [PATCH] Introducting `-[UIManager.setLocalData:forView:]`, the way to provide environmental data to ShadowView Summary: In some cases we need a way to specify some environmental data to shadow view to improve layout (or do something similar), so `localData` serves these needs. For example, any stateful embedded native views may benefit from this. Have in mind that this data is not supposed to interfere with the state of the shadow view. Reviewed By: mmmulani Differential Revision: D5884711 fbshipit-source-id: f0bf66e4608894ec4479b8aca262afcfba6b9f4b --- React/Modules/RCTUIManager.h | 11 +++++++++++ React/Modules/RCTUIManager.m | 14 ++++++++++++++ React/Views/RCTShadowView.h | 12 ++++++++++++ 3 files changed, 37 insertions(+) diff --git a/React/Modules/RCTUIManager.h b/React/Modules/RCTUIManager.h index 6e96bc98f..6fddf984f 100644 --- a/React/Modules/RCTUIManager.h +++ b/React/Modules/RCTUIManager.h @@ -79,6 +79,17 @@ RCT_EXTERN NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplier */ - (void)setAvailableSize:(CGSize)availableSize forRootView:(UIView *)rootView; +/** + * Sets local data for a shadow view corresponded with given view. + * In some cases we need a way to specify some environmental data to shadow view + * to improve layout (or do something similar), so `localData` serves these needs. + * For example, any stateful embedded native views may benefit from this. + * Have in mind that this data is not supposed to interfere with the state of + * the shadow view. + * Please respect one-directional data flow of React. + */ +- (void)setLocalData:(NSObject *)localData forView:(UIView *)view; + /** * Set the size of a view. This might be in response to a screen rotation * or some other layout event outside of the React-managed view hierarchy. diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index aae34be74..b7c1db2fa 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -339,6 +339,20 @@ BOOL RCTIsUIManagerQueue() }); } +- (void)setLocalData:(NSObject *)localData forView:(UIView *)view +{ + RCTAssertMainQueue(); + NSNumber *tag = view.reactTag; + + dispatch_async(RCTGetUIManagerQueue(), ^{ + RCTShadowView *shadowView = self->_shadowViewRegistry[tag]; + RCTAssert(shadowView != nil, @"Could not locate shadow view with tag #%@", tag); + + shadowView.localData = localData; + [self setNeedsLayout]; + }); +} + /** * TODO(yuwang): implement the nativeID functionality in a more efficient way * instead of searching the whole view tree diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index 8f34abdba..3ab70b68c 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -58,6 +58,18 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry @property (nonatomic, strong) UIColor *backgroundColor; // Used to propagate to children @property (nonatomic, copy) RCTDirectEventBlock onLayout; +/** + * In some cases we need a way to specify some environmental data to shadow view + * to improve layout (or do something similar), so `localData` serves these needs. + * For example, any stateful embedded native views may benefit from this. + * Have in mind that this data is not supposed to interfere with the state of + * the shadow view. + * Please respect one-directional data flow of React. + * Use `-[RCTUIManager setLocalData:forView:]` to set this property + * (to provide local/environmental data for a shadow view) from the main thread. + */ +@property (nonatomic, strong) NSObject *localData; + /** * isNewView - Used to track the first time the view is introduced into the hierarchy. It is initialized YES, then is * set to NO in RCTUIManager after the layout pass is done and all frames have been extracted to be applied to the