iOS: refact layout use measure state to control when it self is most,but supernode is fit

This commit is contained in:
pengfei.zhou 2022-08-19 12:04:22 +08:00 committed by osborn
parent 3da39cff48
commit 8d5350898a

View File

@ -92,6 +92,8 @@ - (DoricLayout *)doricLayout {
@end @end
@interface DoricLayout () @interface DoricLayout ()
@property(nonatomic, assign) bool needRemeasure;
@property(nonatomic, assign) bool remeasuring;
@end @end
@implementation DoricLayout @implementation DoricLayout
@ -103,6 +105,8 @@ - (instancetype)init {
_maxHeight = CGFLOAT_MAX; _maxHeight = CGFLOAT_MAX;
_minWidth = -1; _minWidth = -1;
_minHeight = -1; _minHeight = -1;
_needRemeasure = NO;
_remeasuring = NO;
} }
return self; return self;
} }
@ -284,13 +288,15 @@ - (CGFloat)addHeightPadding:(CGFloat)size {
- (bool)needFitWidth { - (bool)needFitWidth {
return self.widthSpec == DoricLayoutFit return self.widthSpec == DoricLayoutFit
|| (self.widthSpec == DoricLayoutMost && self.superLayout.needFitWidth) || (self.widthSpec == DoricLayoutMost && self.superLayout.needFitWidth
&& (!self.superLayout.remeasuring || self.inHLayout))
|| (self.widthSpec == DoricLayoutJust && self.hasWidthWeight); || (self.widthSpec == DoricLayoutJust && self.hasWidthWeight);
} }
- (bool)needFitHeight { - (bool)needFitHeight {
return self.heightSpec == DoricLayoutFit return self.heightSpec == DoricLayoutFit
|| (self.heightSpec == DoricLayoutMost && self.superLayout.needFitHeight) || (self.heightSpec == DoricLayoutMost && self.superLayout.needFitHeight
&& (!self.superLayout.remeasuring || self.inVLayout))
|| (self.heightSpec == DoricLayoutJust && self.hasHeightWeight); || (self.heightSpec == DoricLayoutJust && self.hasHeightWeight);
} }
@ -369,6 +375,8 @@ - (void)measureSelf:(CGSize)remainingSize limitTo:(CGSize)limitSize {
} }
- (void)measureSelf:(CGSize)remainingSize limitTo:(CGSize)limitSize restrain:(bool)needRestrain { - (void)measureSelf:(CGSize)remainingSize limitTo:(CGSize)limitSize restrain:(bool)needRestrain {
self.needRemeasure = NO;
self.remeasuring = NO;
[self measureContent:[self removeSizePadding:remainingSize] [self measureContent:[self removeSizePadding:remainingSize]
limitTo:[self removeSizePadding:limitSize]]; limitTo:[self removeSizePadding:limitSize]];
@ -404,12 +412,30 @@ - (void)measureSelf:(CGSize)remainingSize limitTo:(CGSize)limitSize restrain:(bo
self.measuredHeight = self.height; self.measuredHeight = self.height;
} }
if (needRestrain && [self restrain:limitSize] && self.layoutType != DoricUndefined) { if (needRestrain
&& [self restrain:limitSize]
&& self.layoutType != DoricUndefined
) {
CGSize size = [self removeSizePadding:CGSizeMake( CGSize size = [self removeSizePadding:CGSizeMake(
self.measuredWidth, self.measuredWidth,
self.measuredHeight)]; self.measuredHeight)];
[self measureSelf:size limitTo:size restrain:NO]; [self measureSelf:size limitTo:size restrain:NO];
} }
if (self.needRemeasure) {
CGSize size = [self removeSizePadding:CGSizeMake(
self.measuredWidth,
self.measuredHeight)];
self.remeasuring = YES;
[self measureContent:size
limitTo:size];
self.remeasuring = NO;
}
if ((self.mostWidth && self.superLayout.needFitWidth)
|| (self.mostHeight && self.superLayout.needFitHeight)) {
self.superLayout.needRemeasure = YES;
}
} }
#pragma measureContent #pragma measureContent
@ -487,8 +513,7 @@ - (void)measureVLayoutContent:(CGSize)remaining limitTo:(CGSize)limit {
if (had) { if (had) {
contentHeight -= self.spacing; contentHeight -= self.spacing;
} }
if (contentWeight > 0 && !self.fitHeight && !self.hasHeightWeight) {
if (contentWeight > 0 && !self.fitHeight) {
CGFloat extra = remaining.height - contentHeight; CGFloat extra = remaining.height - contentHeight;
contentWidth = 0; contentWidth = 0;
contentHeight = 0; contentHeight = 0;
@ -677,12 +702,6 @@ - (void)layoutStack {
if (layout.disabled) { if (layout.disabled) {
continue; continue;
} }
if (self.needFitWidth && layout.mostWidth) {
layout.measuredWidth = self.contentWidth - layout.marginLeft - layout.marginRight;
}
if (self.needFitHeight && layout.mostHeight) {
layout.measuredHeight = self.contentHeight - layout.marginTop - layout.marginBottom;
}
[layout layout]; [layout layout];
DoricGravity gravity = layout.alignment; DoricGravity gravity = layout.alignment;
if ((gravity & DoricGravityLeft) == DoricGravityLeft) { if ((gravity & DoricGravityLeft) == DoricGravityLeft) {
@ -736,9 +755,6 @@ - (void)layoutVLayout {
if (layout.disabled) { if (layout.disabled) {
continue; continue;
} }
if (self.needFitWidth && layout.mostWidth) {
layout.measuredWidth = self.contentWidth - layout.marginLeft - layout.marginRight;
}
[layout layout]; [layout layout];
DoricGravity gravity = layout.alignment | self.gravity; DoricGravity gravity = layout.alignment | self.gravity;
if ((gravity & DoricGravityLeft) == DoricGravityLeft) { if ((gravity & DoricGravityLeft) == DoricGravityLeft) {
@ -779,10 +795,6 @@ - (void)layoutHLayout {
continue; continue;
} }
if (self.needFitHeight && layout.mostHeight) {
layout.measuredHeight = self.contentHeight - layout.marginTop - layout.marginBottom;
}
[layout layout]; [layout layout];
DoricGravity gravity = layout.alignment | self.gravity; DoricGravity gravity = layout.alignment | self.gravity;