From 95a16435f3e1a70372b8fa2f0fff5fa6030213f5 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Tue, 23 Aug 2022 17:50:46 +0800 Subject: [PATCH] iOS: align DoricLayout to LinearLayout logic --- doric-iOS/Pod/Classes/Shader/DoricLayouts.h | 2 + doric-iOS/Pod/Classes/Shader/DoricLayouts.m | 116 +++++++++++++++++--- 2 files changed, 102 insertions(+), 16 deletions(-) diff --git a/doric-iOS/Pod/Classes/Shader/DoricLayouts.h b/doric-iOS/Pod/Classes/Shader/DoricLayouts.h index 2c867677..dffe84e6 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricLayouts.h +++ b/doric-iOS/Pod/Classes/Shader/DoricLayouts.h @@ -108,6 +108,8 @@ typedef NS_ENUM(NSInteger, DoricGravity) { @property(nonatomic, assign) CGFloat contentWidth; @property(nonatomic, assign) CGFloat contentHeight; + +@property(nonatomic, assign) CGFloat contentWeight; - (instancetype)init; - (void)measure:(CGSize)targetSize; diff --git a/doric-iOS/Pod/Classes/Shader/DoricLayouts.m b/doric-iOS/Pod/Classes/Shader/DoricLayouts.m index f7de6eb6..05cd8197 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricLayouts.m +++ b/doric-iOS/Pod/Classes/Shader/DoricLayouts.m @@ -137,6 +137,10 @@ - (void)measure:(CGSize)targetSize { #pragma helper +- (BOOL)remeasuring { + return _remeasuring || [self.superLayout remeasuring]; +} + - (BOOL)hasWidthWeight { return self.inHLayout && self.weight > 0; } @@ -212,6 +216,10 @@ - (BOOL)inHLayout { return self.superLayout.layoutType == DoricHLayout; } +- (BOOL)inStack { + return self.superLayout.layoutType == DoricStack; +} + - (CGFloat)takenWidth { return self.measuredWidth + self.marginLeft + self.marginRight; } @@ -287,17 +295,65 @@ - (CGFloat)addHeightPadding:(CGFloat)size { } - (BOOL)needFitWidth { - return self.widthSpec == DoricLayoutFit - || (self.widthSpec == DoricLayoutMost && self.superLayout.needFitWidth - && (!self.superLayout.remeasuring || self.inHLayout)) - || (self.widthSpec == DoricLayoutJust && self.hasWidthWeight); + if (self.widthSpec == DoricLayoutFit) { + return YES; + } + if (self.widthSpec == DoricLayoutJust) { + return self.hasWidthWeight; + } + if (self.widthSpec == DoricLayoutMost) { + if (self.superLayout.needFitWidth) { + if (!self.remeasuring) { + return YES; + } + if (self.inHLayout) { + if (self.superLayout.fitWidth) { + return YES; + } + if (!self.superLayout.inHLayout) { + return YES; + } + if (self.superLayout.superLayout.inStack) { + return YES; + } + if (self.superLayout.superLayout.superMostHeight) { + return YES; + } + } + } + } + return NO; } - (BOOL)needFitHeight { - return self.heightSpec == DoricLayoutFit - || (self.heightSpec == DoricLayoutMost && self.superLayout.needFitHeight - && (!self.superLayout.remeasuring || self.inVLayout)) - || (self.heightSpec == DoricLayoutJust && self.hasHeightWeight); + if (self.heightSpec == DoricLayoutFit) { + return YES; + } + if (self.heightSpec == DoricLayoutJust) { + return self.hasHeightWeight; + } + if (self.heightSpec == DoricLayoutMost) { + if (self.superLayout.needFitHeight) { + if (!self.remeasuring) { + return YES; + } + if (self.inVLayout) { + if (self.superLayout.fitHeight) { + return YES; + } + if (!self.superLayout.inVLayout) { + return YES; + } + if (self.superLayout.superLayout.inStack) { + return YES; + } + if (self.superLayout.superLayout.superMostWidth) { + return YES; + } + } + } + } + return NO; } @@ -555,10 +611,10 @@ - (void)measureVLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { had = YES; CGSize childRemaining = [layout removeMargin:CGSizeMake( remaining.width, - layout.hasHeightWeight ? remaining.height : remaining.height - contentHeight)]; + (self.contentWeight > 0 || layout.hasHeightWeight) ? remaining.height : remaining.height - contentHeight)]; CGSize childLimit = [layout removeMargin:CGSizeMake( limit.width, - layout.hasHeightWeight ? limit.height : limit.height - contentHeight)]; + (self.contentWeight > 0 || layout.hasHeightWeight) ? limit.height : limit.height - contentHeight)]; [layout measureSelf:childRemaining limitTo:childLimit]; if (!(layout.mostWidth && self.fitWidth)) { existsContent = YES; @@ -567,6 +623,7 @@ - (void)measureVLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { contentHeight += layout.takenHeight + self.spacing; contentWeight += layout.weight; } + self.contentWeight = contentWeight; if (!existsContent) { for (__kindof UIView *subview in self.view.subviews) { DoricLayout *layout = subview.doricLayout; @@ -579,7 +636,22 @@ - (void)measureVLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { if (had) { contentHeight -= self.spacing; } - if (contentWeight > 0 && !self.fitHeight && !self.hasHeightWeight) { + BOOL reassign = NO; + if (contentWeight > 0) { + if (self.needFitHeight && self.inVLayout) { + if (self.remeasuring) { + reassign = YES; + } else { + self.superLayout.needRemeasure = YES; + } + } + + if (!self.needFitHeight && !self.hasHeightWeight) { + reassign = YES; + } + } + + if (reassign) { CGFloat extra = remaining.height - contentHeight; contentWidth = 0; contentHeight = 0; @@ -607,7 +679,6 @@ - (void)measureVLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { contentHeight -= self.spacing; } } - self.contentWidth = contentWidth; self.contentHeight = contentHeight; @@ -624,10 +695,10 @@ - (void)measureHLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { } had = YES; CGSize childRemaining = [layout removeMargin:CGSizeMake( - layout.hasWidthWeight ? remaining.width : remaining.width - contentWidth, + (self.contentWeight > 0 || layout.hasWidthWeight) ? remaining.width : remaining.width - contentWidth, remaining.height)]; CGSize childLimit = [layout removeMargin:CGSizeMake( - layout.hasWidthWeight ? limit.width : limit.width - contentWidth, + (self.contentWeight > 0 || layout.hasWidthWeight) ? limit.width : limit.width - contentWidth, limit.height)]; [layout measureSelf:childRemaining limitTo:childLimit]; contentWidth += layout.takenWidth + self.spacing; @@ -637,6 +708,7 @@ - (void)measureHLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { } contentWeight += layout.weight; } + self.contentWeight = contentWeight; if (!existsContent) { for (__kindof UIView *subview in self.view.subviews) { DoricLayout *layout = subview.doricLayout; @@ -649,8 +721,20 @@ - (void)measureHLayoutContent:(CGSize)remaining limitTo:(CGSize)limit { if (had) { contentWidth -= self.spacing; } - - if (contentWeight > 0 && !self.fitWidth) { + BOOL reassign = NO; + if (contentWeight > 0) { + if (self.needFitWidth && self.inHLayout) { + if (self.remeasuring) { + reassign = YES; + } else { + self.superLayout.needRemeasure = YES; + } + } + if (!self.needFitWidth && !self.hasWidthWeight) { + reassign = YES; + } + } + if (reassign) { CGFloat extra = remaining.width - contentWidth; contentWidth = 0; contentHeight = 0;