Add isDirty property and make markDirty less crashy/more performant.
Summary: For some internal Instagram diffs, and some external ones (auto-detection of dirty nodes). We need to give the dirty properties a little love. This adds a getter to find out if your node is dirty, and makes sure that the leaf node is properly setup before it is marked dirty to prevent a crash. Reviewed By: emilsjolander Differential Revision: D4549241 fbshipit-source-id: 36eda6fdb4ea7f968d126aab6da67896f4a01d40
This commit is contained in:
committed by
Facebook Github Bot
parent
abf142ea3f
commit
55fe6f0bc9
@@ -42,3 +42,5 @@ view.configureLayout { (layout) in
|
|||||||
layout.height = 50
|
layout.height = 50
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Added new `isDirty` property, and make `markDirty` a little more performant.
|
||||||
|
@@ -111,6 +111,12 @@
|
|||||||
*/
|
*/
|
||||||
@property (nonatomic, readonly, assign) BOOL isLeaf;
|
@property (nonatomic, readonly, assign) BOOL isLeaf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return's a BOOL indicating if a view is dirty. When a node is dirty
|
||||||
|
it usually indicates that it will be remeasured on the next layout pass.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, readonly, assign) BOOL isDirty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Mark that a view's layout needs to be recalculated. Only works for leaf views.
|
Mark that a view's layout needs to be recalculated. Only works for leaf views.
|
||||||
*/
|
*/
|
||||||
|
@@ -120,11 +120,26 @@ YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEd
|
|||||||
YGNodeFree(self.node);
|
YGNodeFree(self.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)isDirty
|
||||||
|
{
|
||||||
|
return YGNodeIsDirty(self.node);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)markDirty
|
- (void)markDirty
|
||||||
{
|
{
|
||||||
if (self.isLeaf) {
|
if (self.isDirty || !self.isLeaf) {
|
||||||
YGNodeMarkDirty(self.node);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Yoga is not happy if we try to mark a node as "dirty" before we have set
|
||||||
|
// the measure function. Since we already know that this is a leaf,
|
||||||
|
// this *should* be fine. Forgive me Hack Gods.
|
||||||
|
const YGNodeRef node = self.node;
|
||||||
|
if (YGNodeGetMeasureFunc(node) == NULL) {
|
||||||
|
YGNodeSetMeasureFunc(node, YGMeasureView);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGNodeMarkDirty(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger)numberOfChildren
|
- (NSUInteger)numberOfChildren
|
||||||
|
@@ -153,6 +153,24 @@
|
|||||||
XCTAssertEqual(25, view2.frame.origin.y);
|
XCTAssertEqual(25, view2.frame.origin.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testMarkingDirtyOnlyWorksOnLeafNodes
|
||||||
|
{
|
||||||
|
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
|
container.yoga.isEnabled = YES;
|
||||||
|
|
||||||
|
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
|
subview.yoga.isEnabled = YES;
|
||||||
|
[container addSubview:subview];
|
||||||
|
|
||||||
|
XCTAssertFalse(container.yoga.isDirty);
|
||||||
|
[container.yoga markDirty];
|
||||||
|
XCTAssertFalse(container.yoga.isDirty);
|
||||||
|
|
||||||
|
XCTAssertFalse(subview.yoga.isDirty);
|
||||||
|
[subview.yoga markDirty];
|
||||||
|
XCTAssertTrue(subview.yoga.isDirty);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation
|
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation
|
||||||
{
|
{
|
||||||
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
|
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
|
||||||
|
Reference in New Issue
Block a user