SwiftUI Table列按需显示隐藏实现方案求助(基于AppStorage)
解决SwiftUI Table组件列显示隐藏的动态配置问题
直接用@ViewBuilder封装列的构建逻辑就能解决这个问题,TableColumnBuilder本身不允许在闭包内直接写条件,但把条件判断抽离到单独的@ViewBuilder函数里,再传给Table的columns参数就行,完全不用枚举所有排列组合。
具体实现代码
import SwiftUI struct User: Identifiable { let id = UUID() let name: String let age: Int let email: String } struct ContentView: View { // 用AppStorage持久化列的可见状态 @AppStorage("showNameCol") private var showName = true @AppStorage("showAgeCol") private var showAge = true @AppStorage("showEmailCol") private var showEmail = true let sampleUsers: [User] = [ .init(name: "Alice", age: 32, email: "alice@demo.com"), .init(name: "Bob", age: 28, email: "bob@demo.com"), .init(name: "Charlie", age: 40, email: "charlie@demo.com") ] // 用@ViewBuilder封装列的条件构建逻辑 @ViewBuilder private func tableColumns() -> some TableColumnContent<User> { if showName { TableColumn("姓名") { user in Text(user.name) } } if showAge { TableColumn("年龄") { user in Text("\(user.age)") .frame(maxWidth: .infinity, alignment: .trailing) } } if showEmail { TableColumn("邮箱") { user in Text(user.email) .foregroundColor(.secondary) } } } var body: some View { Table(sampleUsers, columns: tableColumns) .toolbar { // 添加列设置按钮,弹出面板让用户切换可见性 Button(action: {}) { Image(systemName: "slider.horizontal.3") } .popover(isPresented: .constant(false)) { VStack(spacing: 12) { Toggle("显示姓名列", isOn: $showName) Toggle("显示年龄列", isOn: $showAge) Toggle("显示邮箱列", isOn: $showEmail) Spacer() } .padding() .frame(width: 240) } } .frame(minWidth: 600, minHeight: 400) } }
原理说明
@ViewBuilder标记的函数可以返回动态的视图集合,这里就是根据AppStorage的布尔值动态包含或排除对应的TableColumn。- 把列构建逻辑抽离后,Table的
columns参数能正确识别这个动态生成的列集合,不会触发TableColumnBuilder的语法限制。 AppStorage会自动持久化用户的列可见性设置,重启应用后依然有效。
内容的提问来源于stack exchange,提问作者DudeOnRock
相关产品推荐
相关产品推荐

