Take care of pixel rounding for UIView.
Summary: You can lose a lot of performance on UIView's if they are not pixel-aligned. This protects it from happening in views which use css-layout. Reviewed By: emilsjolander Differential Revision: D4140306 fbshipit-source-id: 53493c08c084a7e3dcd4e05f6a665a99340ea5a6
This commit is contained in:
committed by
Facebook Github Bot
parent
18fe0959f0
commit
366a61af8d
@@ -78,4 +78,33 @@
|
|||||||
XCTAssertTrue(CGSizeEqualToSize(constrainedSize, actualSize), @"Actual Size: %@", NSStringFromCGSize(actualSize));
|
XCTAssertTrue(CGSizeEqualToSize(constrainedSize, actualSize), @"Actual Size: %@", NSStringFromCGSize(actualSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testFrameAndOriginPlacement
|
||||||
|
{
|
||||||
|
const CGSize containerSize = CGSizeMake(320, 50);
|
||||||
|
|
||||||
|
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)];
|
||||||
|
[container css_setUsesFlexbox:YES];
|
||||||
|
[container css_setFlexDirection:CSSFlexDirectionRow];
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
|
[subview css_setUsesFlexbox:YES];
|
||||||
|
[subview css_setFlexGrow:1];
|
||||||
|
|
||||||
|
[container addSubview:subview];
|
||||||
|
}
|
||||||
|
[container css_applyLayout];
|
||||||
|
|
||||||
|
XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:1].frame));
|
||||||
|
XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:1].frame, [container.subviews objectAtIndex:2].frame));
|
||||||
|
XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:2].frame));
|
||||||
|
|
||||||
|
CGFloat totalWidth = 0;
|
||||||
|
for (UIView *view in container.subviews) {
|
||||||
|
totalWidth += view.bounds.size.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(containerSize.width, totalWidth, @"The container's width is %.6f, the subviews take up %.6f", containerSize.width, totalWidth);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@@ -277,22 +277,43 @@ static void _attachNodesRecursive(UIView *view) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CGFloat _roundPixelValue(CGFloat value)
|
||||||
|
{
|
||||||
|
static CGFloat scale;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^(){
|
||||||
|
scale = [UIScreen mainScreen].scale;
|
||||||
|
});
|
||||||
|
|
||||||
|
return round(value * scale) / scale;
|
||||||
|
}
|
||||||
|
|
||||||
static void _updateFrameRecursive(UIView *view) {
|
static void _updateFrameRecursive(UIView *view) {
|
||||||
|
NSAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread.");
|
||||||
CSSNodeRef node = [view cssNode];
|
CSSNodeRef node = [view cssNode];
|
||||||
const BOOL usesFlexbox = [view css_usesFlexbox];
|
|
||||||
const BOOL isLeaf = !usesFlexbox || view.subviews.count == 0;
|
const CGPoint topLeft = {
|
||||||
|
CSSNodeLayoutGetLeft(node),
|
||||||
|
CSSNodeLayoutGetTop(node),
|
||||||
|
};
|
||||||
|
|
||||||
|
const CGPoint bottomRight = {
|
||||||
|
topLeft.x + CSSNodeLayoutGetWidth(node),
|
||||||
|
topLeft.y + CSSNodeLayoutGetHeight(node),
|
||||||
|
};
|
||||||
|
|
||||||
view.frame = (CGRect) {
|
view.frame = (CGRect) {
|
||||||
.origin = {
|
.origin = {
|
||||||
.x = CSSNodeLayoutGetLeft(node),
|
.x = _roundPixelValue(topLeft.x),
|
||||||
.y = CSSNodeLayoutGetTop(node),
|
.y = _roundPixelValue(topLeft.y),
|
||||||
},
|
},
|
||||||
.size = {
|
.size = {
|
||||||
.width = CSSNodeLayoutGetWidth(node),
|
.width = _roundPixelValue(bottomRight.x) - _roundPixelValue(topLeft.x),
|
||||||
.height = CSSNodeLayoutGetHeight(node),
|
.height = _roundPixelValue(bottomRight.y) - _roundPixelValue(topLeft.y),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const BOOL isLeaf = ![view css_usesFlexbox] || view.subviews.count == 0;
|
||||||
if (!isLeaf) {
|
if (!isLeaf) {
|
||||||
for (NSUInteger i = 0; i < view.subviews.count; i++) {
|
for (NSUInteger i = 0; i < view.subviews.count; i++) {
|
||||||
_updateFrameRecursive(view.subviews[i]);
|
_updateFrameRecursive(view.subviews[i]);
|
||||||
|
Reference in New Issue
Block a user