LazyVGrid中嵌套ForEach内的Text视图不显示问题咨询
原因分析
SwiftUI 的 LazyVGrid 要求直接子视图是独立的网格项,而 ForEach 在 ViewBuilder 中的展开规则有明显区别:
- 当你在
ForEach的闭包里直接返回多个视图(比如你第二段代码里的Text("aaa")+Text("bbb")),ViewBuilder会自动把这些视图合并后平铺到父容器的视图序列中,每个Text都会成为LazyVGrid的独立网格项,因此能正常显示。 - 但如果闭包里返回的是另一个
ForEach(也就是你第一段代码的嵌套写法),内层的ForEach会被当作单个视图容器,而不是把它内部的Text平铺到LazyVGrid里。外层ForEach(categories)的每个迭代项都会对应一个这样的容器视图,这个容器会被LazyVGrid当成单个网格项。如果你的网格列数或categories数量的搭配导致这个容器被压缩,内部的Text("aaa")就会被挤得无法显示。
解决方法
要让嵌套循环的 Text 正常显示,需要把内层视图平铺到 LazyVGrid 中,推荐两种方式:
方式一:扁平化数据序列
把 categories 和 months 的组合转换成扁平的序列,直接遍历这个序列生成网格项:
LazyVGrid(columns: dataColumns) { ForEach(months, id: \.self) { month in Text("\(dateFormatter.string(from: month))") } // 扁平化category与month的组合 ForEach(categories.flatMap { category in months.map { (category, $0) } }, id: \.1) { _, month in Text("aaa") } }
方式二:用@ViewBuilder辅助展开嵌套循环
通过自定义的 @ViewBuilder 函数来处理嵌套循环,让内部视图自动展开:
@ViewBuilder func buildCategoryMonthCells() -> some View { ForEach(categories) { category in ForEach(months, id: \.self) { month in Text("aaa") } } } // 在LazyVGrid中使用该函数 LazyVGrid(columns: dataColumns) { ForEach(months, id: \.self) { month in Text("\(dateFormatter.string(from: month))") } buildCategoryMonthCells() }
内容的提问来源于stack exchange,提问作者Dawy
相关产品推荐
相关产品推荐

