自定义SwiftUI布局中sizeThatFits返回fixedSize子视图无效尺寸
解决SwiftUI自定义布局中fixedSize导致sizeThatFits计算高度偏差的问题
当给Text添加.fixedSize(horizontal: false, vertical: true)后,用.sizeThatFits(.unspecified)计算子视图高度出现偏差,核心原因是这个尺寸提案没有给子视图提供实际可用的宽度约束。
.fixedSize(vertical: true)会让Text根据内容自动换行,但它需要知道可用宽度才能准确计算所需高度。.unspecified的提案相当于给子视图无限宽,Text会尽量减少换行,因此计算出的高度比实际渲染时偏小;而实际渲染时子视图受容器宽度限制,换行更多,高度自然更大。
修复方案
调用子视图的sizeThatFits时,传入包含容器实际宽度的尺寸提案,让子视图基于真实可用宽度计算高度:
public func sizeThatFits( proposal: ProposedViewSize, subviews: Subviews, cache: inout () ) -> CGSize { var totalHeight: CGFloat = 0 let rows = computeRows(subviews: subviews, proposal: proposal) let containerWidth = proposal.replacingUnspecifiedDimensions().width rows.forEach { cells in // 用容器宽度作为子视图的宽度约束,高度保持未指定 let sizes = cells.map { $0.sizeThatFits(ProposedViewSize(width: containerWidth, height: .unspecified)) } let maxViewHeight = sizes.map(\.height).max() ?? 0 totalHeight += maxViewHeight } totalHeight += CGFloat(rows.count - 1) * spacing.height return CGSize( width: containerWidth, height: totalHeight ) }
这样修改后,子视图会按照实际渲染时的宽度约束计算高度,最终容器的总高度计算就会和实际视图高度一致。
内容的提问来源于stack exchange,提问作者Igor Ševtšenko
相关产品推荐
相关产品推荐

