import SwiftUI
struct FlexibleView<Data: Collection, Content: View>: View where Data.Element: Hashable {
let data: Data //数据元
let spacing: CGFloat //行/列间距
let availableWidth: CGFloat //总宽度
var alignment: HorizontalAlignment = .leading
var targetline: Int = 3 //预估行数, 使高度能空白填充, 和其他数量不同的地方保持高度一致
let content: (Data.Element) -> Content
@State var elementsSize: [Data.Element: CGSize] = [:]
var body: some View {
if data.isEmpty {
EmptyView()
}else{
ZStack(alignment: .topLeading) {
VStack(alignment: alignment, spacing: spacing) {
ForEach(0..<targetline, id: \.self) { _ in
content(data.first!)//每个
.fixedSize()
.opacity(0)
}
}
VStack(alignment: alignment, spacing: spacing) {
ForEach(computeRows(), id: \.self) { rowElements in
HStack(spacing: spacing) {//每行
ForEach(rowElements, id: \.self) { element in
content(element)//每个
.fixedSize()
.readSize { size in
elementsSize[element] = size
}
}
}
}
}
}
}
}
func computeRows() -> [[Data.Element]] {//计算行数和每个
var rows: [[Data.Element]] = [[]]
var currentRow = 0
var remainingWidth = availableWidth
for element in data {
let elementSize = elementsSize[element, default: CGSize(width: availableWidth, height: 1)]
if remainingWidth - (elementSize.width + spacing) >= -4 {
rows[currentRow].append(element)
} else {
currentRow = currentRow + 1
rows.append([element])
remainingWidth = availableWidth
}
remainingWidth = remainingWidth - (elementSize.width + spacing)
}
return rows
}
}
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
public extension View {
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {//size识别
return background(
GeometryReader { geometryProxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometryProxy.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
}
SwiftUI-FlexibleView-自动预估高度-Grid布局自动居左排列
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
相关阅读更多精彩内容
- flex布局 justify-content:space-between; 解决最后一排数量不够自动向两端排列问题...
- Layout组件使用以下配置: 效果如下图所示 cocosCreator版本:1.9.2 这个效果明显不是我想要的...
- iOS 预估值estimatedHeight实现headerView和cell自适应高度布局机制踩坑
- 自动布局系列的代码可见工程:https://github.com/noahls/AutoLayoutDemo UI...