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社区最常见的处理方式,既避免了问题又保持代码清晰。其他方案作为备选,根据实际复杂度选用。
