SwiftUI+MVVM场景下点击排序按钮切换列表无响应问题求解
问题根源
你代码的核心问题出在SortButton组件的点击逻辑实现上:你在Button的action闭包里仅定义了show(button:)函数,但是从未调用过该函数,点击按钮时没有任何逻辑执行,绑定的bools值不会发生变化,自然不会触发列表刷新。
修复代码
直接修改SortButton的实现,去掉多余的嵌套函数定义,直接执行切换逻辑即可:
import SwiftUI struct SortButton: View { var name: Select @Binding var bools: [String : Bool] var body: some View { Button { // 重置所有按钮状态 Select.allCases.forEach { button in bools[button.rawValue] = false } // 激活当前点击的按钮 bools[name.rawValue] = true } label: { Text(name.rawValue) } } }
可选优化建议
为了更符合MVVM设计模式、进一步减少重复代码,你还可以做如下调整:
- 在ViewModel中给
bools添加属性观察者,自动触发数组刷新,不需要在视图层重复添加onChange监听:
class ContentViewModel: ObservableObject { @Published var contentArray = [String]() // 添加didSet自动触发数组更新 @Published var bools = [String : Bool]() { didSet { getArray() } } private let arrayOne = ["One", "Two", "Three"] private let arrayTwo = ["Four", "Five", "Six"] private let arrayThree = ["Seven", "Eight", "Nine"] func setButtons() { Select.allCases.forEach { button in bools[button.rawValue] = false } bools["arrayOne"] = true } // 优化解包逻辑,避免强制解包崩溃 func getArray() { if bools["arrayOne"] == true { contentArray = arrayOne } else if bools["arrayTwo"] == true { contentArray = arrayTwo } else if bools["arrayThree"] == true { contentArray = arrayThree } } }
- 优化后的
ContentView可以删掉所有重复的onChange代码,更简洁:
struct ContentView: View { @StateObject private var vm = ContentViewModel() var body: some View { VStack { HStack { SortButton(name: .arrayOne, bools: $vm.bools) SortButton(name: .arrayTwo, bools: $vm.bools) SortButton(name: .arrayThree, bools: $vm.bools) } List { ForEach(vm.contentArray, id: \.self) { content in Text(content) } } } .onAppear { vm.setButtons() } } }
内容的提问来源于stack exchange,提问作者sans connaissance
相关产品推荐
相关产品推荐

