Sanitize results from sizeThatFits:, fix bug where only one of the measure modes is CSSMeasureModeExactly.
Summary: As I've begun to integrate this into the codebase, I've found that sometimes our layouts are affected by bad implementations of sizeThatFits:. For example, in certain configurations of UILabel it won't take clipping into account and return a size that is much larger than the max size we requested. This adds some checks to make sure we never return a size that is larger than the one specified by `_measure`. This also fixes the bug where `CSSMeasureModeExactly` won't be applied if the measure mode for other parameter is node `CSSMeasureModeExactly`. Reviewed By: emilsjolander Differential Revision: D4131195 fbshipit-source-id: 4659fd83892a2c149b3b70733b06b19217507bf9
This commit is contained in:
committed by
Facebook Github Bot
parent
6165d7a2be
commit
1ffce3edb1
@@ -205,6 +205,7 @@ static CSSSize _measure(
|
||||
float height,
|
||||
CSSMeasureMode heightMode)
|
||||
{
|
||||
// sizeThatFits: can be expensive. If we can avoid it, lets do it.
|
||||
if ((widthMode == CSSMeasureModeExactly) && (heightMode == CSSMeasureModeExactly)) {
|
||||
return (CSSSize) {
|
||||
.width = width,
|
||||
@@ -212,18 +213,38 @@ static CSSSize _measure(
|
||||
};
|
||||
}
|
||||
|
||||
const CGFloat constrainedWidth = (widthMode == CSSMeasureModeUndefined) ? CGFLOAT_MAX : width;
|
||||
const CGFloat constrainedHeight = (heightMode == CSSMeasureModeUndefined) ? CGFLOAT_MAX: height;
|
||||
|
||||
UIView *view = (__bridge UIView*) CSSNodeGetContext(node);
|
||||
const CGSize sizeThatFits = [view sizeThatFits:(CGSize) {
|
||||
.width = widthMode == CSSMeasureModeUndefined ? CGFLOAT_MAX : width,
|
||||
.height = heightMode == CSSMeasureModeUndefined ? CGFLOAT_MAX : height,
|
||||
.width = constrainedWidth,
|
||||
.height = constrainedHeight,
|
||||
}];
|
||||
|
||||
return (CSSSize) {
|
||||
.width = sizeThatFits.width,
|
||||
.height = sizeThatFits.height,
|
||||
.width = _sanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode),
|
||||
.height = _sanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode),
|
||||
};
|
||||
}
|
||||
|
||||
static CGFloat _sanitizeMeasurement(
|
||||
CGFloat constrainedSize,
|
||||
CGFloat measuredSize,
|
||||
CSSMeasureMode measureMode)
|
||||
{
|
||||
CGFloat result;
|
||||
if (measureMode == CSSMeasureModeExactly) {
|
||||
result = constrainedSize;
|
||||
} else if (measureMode == CSSMeasureModeAtMost) {
|
||||
result = MIN(constrainedSize, measuredSize);
|
||||
} else {
|
||||
result = measuredSize;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _attachNodesRecursive(UIView *view) {
|
||||
CSSNodeRef node = [view cssNode];
|
||||
const BOOL usesFlexbox = [view css_usesFlexbox];
|
||||
|
Reference in New Issue
Block a user