From 47839307f3bde76020fe0e05e4d38c8d66640dd4 Mon Sep 17 00:00:00 2001 From: Martin Kralik Date: Fri, 11 Nov 2016 05:22:40 -0800 Subject: [PATCH] proper `reactSuperview` implementation Summary: React view hierarchy doesn't have to always match uiview hierarchy. Plus if we clip view we loose knowledge about view's react superview if we just use `self.superview` as react superview. This diff fixes it by storing a strong ref to reactSuperview in an associated object. This is needed for new view clipping implementation (see the dependent diff). Reviewed By: mmmulani Differential Revision: D4081844 fbshipit-source-id: 9317d9db46fbd474382c5469b7922f88e5ee7568 --- React/Views/UIView+React.m | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/React/Views/UIView+React.m b/React/Views/UIView+React.m index d637e7efaa1..322445845cc 100644 --- a/React/Views/UIView+React.m +++ b/React/Views/UIView+React.m @@ -15,6 +15,13 @@ #import "RCTLog.h" #import "RCTShadowView.h" +@interface RCTWeakObjectContainer : NSObject +@property (nonatomic, weak) id object; +@end + +@implementation RCTWeakObjectContainer +@end + @implementation UIView (React) - (NSNumber *)reactTag @@ -27,6 +34,18 @@ objc_setAssociatedObject(self, @selector(reactTag), reactTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } +- (UIView *)reactSuperview +{ + return [(RCTWeakObjectContainer *)objc_getAssociatedObject(self, @selector(reactSuperview)) object]; +} + +- (void)setReactSuperview:(UIView *)reactSuperview +{ + RCTWeakObjectContainer *wrapper = [RCTWeakObjectContainer new]; + wrapper.object = reactSuperview; + objc_setAssociatedObject(self, @selector(reactSuperview), wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + #if RCT_DEV - (RCTShadowView *)_DEBUG_reactShadowView @@ -61,11 +80,6 @@ return objc_getAssociatedObject(self, _cmd); } -- (UIView *)reactSuperview -{ - return self.superview; -} - - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex { // We access the associated object directly here in case someone overrides @@ -76,6 +90,7 @@ objc_setAssociatedObject(self, @selector(reactSubviews), subviews, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } [subviews insertObject:subview atIndex:atIndex]; + [subview setReactSuperview:self]; } - (void)removeReactSubview:(UIView *)subview @@ -85,6 +100,7 @@ NSMutableArray *subviews = objc_getAssociatedObject(self, @selector(reactSubviews)); [subviews removeObject:subview]; [subview removeFromSuperview]; + [subview setReactSuperview:nil]; } - (NSInteger)reactZIndex