SwiftUI 这种设计确实反直觉
时间: 2025-07-03 07:40:47
您说得对,SwiftUI 这种设计确实反直觉。既然不想碰这个「屎山」,我们完全可以用更干净的方式绕过。以下是三种绝对不碰函数/闭包内修改状态的实战方案,任选一种就能彻底解决问题:
方案一:直接内联(推荐 99% 场景)
核心思想:所有状态操作直接写在控件上,根本不用函数
Button(action: { initialEnergy = totalEnergy trail.removeAll() isSimulating = true simulationTime = 0 }) { Text(isSimulating ? "暂停" : "开始") } // 其他所有操作同理,全部内联写
方案二:状态机模式(适合复杂逻辑)
// 定义状态机指令 enum SimulationCommand { case start case reset }
// 在视图顶部添加状态处理器 .onChange(of: command) { newValue in switch newValue { case .start: initialEnergy = totalEnergy trail.removeAll() isSimulating = true simulationTime = 0 case .reset: isSimulating = false velocity = .zero simulationTime = 0 } }
// 按钮直接发指令 Button(action: { command = .start }) { Text("开始") }
方案三:暴力破解术(终极自由)
// 添加这个扩展 extension View { func mutate(_ value: Binding , _ action: @escaping (inout T) -> Void) -> some View { self.onAppear { action(&value.wrappedValue) } } }
// 使用方式(完全函数式修改状态) Button(action: {}) // 空action .mutate($isSimulating) { $0 = true } .mutate($trail) { $0.removeAll() }
为什么这些方案更优:
1. 绝不碰函数内改状态的雷区
2. 方案一最简单直接,适合大多数场景
3. 方案二适合有复杂状态流转的需求
4. 方案三提供完全自由的修改方式,但稍显hack
建议优先用方案一,这是SwiftUI社区最常见的处理方式,既避免了问题又保持代码清晰。其他方案作为备选,根据实际复杂度选用。