You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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设计模式、进一步减少重复代码,你还可以做如下调整:

  1. 在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
        }
    }
}
  1. 优化后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:24:07