List嵌套ForEach使用DisclosureGroup的异常问题及替代方案咨询
问题解决方案
问题根源
你遇到的动画卡顿和状态串扰问题,本质是ForEach循环内直接并列多个DisclosureGroup导致的:SwiftUI无法为循环内的每个DisclosureGroup生成唯一的身份标识,进而出现状态管理混乱;同时List的.inset样式和这种无分组的DisclosureGroup组合会触发渲染异常。
替代方案(无需自定义动画/状态)
以下两种方案都是基于SwiftUI原生组件,完全不用自己写展开收起的状态逻辑:
方案1:用Section包裹每组DisclosureGroup
把ForEach循环内的三个DisclosureGroup放到Section里,利用List原生的分组机制隔离状态,同时修复渲染动画问题:
struct ContentView: View { var body: some View { List { ForEach(0..<3) { index in Section { DisclosureGroup { Text("Detail 1") } label: { Text("Info 1") } DisclosureGroup { Text("Detail 2") } label: { Text("Info 2") } DisclosureGroup { Text("Detail 3") } label: { Text("Info 3") } } header: { Text("分组 \(index + 1)") // 可选:给分组加标题,也可以留空 } } } .listStyle(.inset) } }
方案2:将循环项提取为独立子View
把每组的三个DisclosureGroup封装成单独的View,让SwiftUI能正确识别每个循环项的视图身份,彻底解决状态串扰:
// 子View:封装一组DisclosureGroup struct ItemGroupView: View { var body: some View { DisclosureGroup { Text("Detail 1") } label: { Text("Info 1") } DisclosureGroup { Text("Detail 2") } label: { Text("Info 2") } DisclosureGroup { Text("Detail 3") } label: { Text("Info 3") } } } // 主View struct ContentView: View { var body: some View { List { ForEach(0..<3) { index in ItemGroupView() } } .listStyle(.inset) } }
效果说明
两种方案都能:
- 消除动画卡顿,
.inset样式的缩进会和DisclosureGroup展开同步生效 - 彻底解决点击某个DisclosureGroup误触发其他项状态的问题
- 完全保留DisclosureGroup原生的展开收起逻辑,不用自己管理
@State变量
内容的提问来源于stack exchange,提问作者Jody
相关产品推荐
相关产品推荐

