Skip to content

Commit

Permalink
Adds the ability to use UIManager to check if a node is an ancestor o…
Browse files Browse the repository at this point in the history
…f other node.

Added @alloy suggestions and refactored the descendant method name
  • Loading branch information
alvaromb authored and alvaromb committed Jun 21, 2016
1 parent 4c3c15f commit afb0f86
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
23 changes: 23 additions & 0 deletions Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,29 @@ - (void)testApplyingLayoutRecursivelyToShadowView
XCTAssertTrue(CGRectEqualToRect([rightView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(330, 120, 100, 200)));
}

- (void)testAncestorCheck
{
RCTShadowView *centerView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];

RCTShadowView *mainView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];

[mainView insertReactSubview:centerView atIndex:0];

RCTShadowView *footerView = [self _shadowViewWithStyle:^(css_style_t *style) {
style->flex = 1;
}];

[self.parentView insertReactSubview:mainView atIndex:0];
[self.parentView insertReactSubview:footerView atIndex:1];

XCTAssertTrue([centerView viewIsDescendantOf:mainView]);
XCTAssertFalse([footerView viewIsDescendantOf:mainView]);
}

- (void)testAssignsSuggestedWidthDimension
{
[self _withShadowViewWithStyle:^(css_style_t *style) {
Expand Down
20 changes: 20 additions & 0 deletions React/Modules/RCTUIManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,26 @@ - (void)setNeedsLayout
}];
}

/**
* Returs if the shadow view provided has the `ancestor` shadow view as
* an actual ancestor.
*/
RCT_EXPORT_METHOD(viewIsDescendantOf:(nonnull NSNumber *)reactTag
ancestor:(nonnull NSNumber *)ancestorReactTag
callback:(RCTResponseSenderBlock)callback)
{
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
RCTShadowView *ancestorShadowView = _shadowViewRegistry[ancestorReactTag];
if (!shadowView) {
return;
}
if (!ancestorShadowView) {
return;
}
BOOL viewIsAncestor = [shadowView viewIsDescendantOf:ancestorShadowView];
callback(@[@(viewIsAncestor)]);
}

static void RCTMeasureLayout(RCTShadowView *view,
RCTShadowView *ancestor,
RCTResponseSenderBlock callback)
Expand Down
5 changes: 5 additions & 0 deletions React/Views/RCTShadowView.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,9 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
*/
- (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor;

/**
* Checks if the current shadow view is a descendant of the provided `ancestor`
*/
- (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor;

@end
11 changes: 11 additions & 0 deletions React/Views/RCTShadowView.m
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ - (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor
return (CGRect){offset, self.frame.size};
}

- (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor
{
NSInteger depth = 30; // max depth to search
RCTShadowView *shadowView = self;
while (depth && shadowView && shadowView != ancestor) {
shadowView = shadowView->_superview;
depth--;
}
return ancestor == shadowView;
}

- (instancetype)init
{
if ((self = [super init])) {
Expand Down

0 comments on commit afb0f86

Please sign in to comment.