SwiftUI中Binding对象状态变更后ContentView未重渲染问题求助
核心原因:你已经通过@Binding成功修改了habit.isDisplayed的值,但没有在视图层将这个状态与按钮的显示逻辑绑定。SwiftUI是状态驱动渲染机制,只有当状态变化关联到视图的可见性或内容时,才会触发重渲染。
解决方案
以下两种方式任选其一即可实现需求:
方式1:在HabitEggButton内部控制自身显示
直接在HabitEggButton中根据habit.isDisplayed判断是否渲染按钮:
import Foundation import SwiftUI struct HabitEggButton: View { @Binding var habit : Habit var body: some View { // 仅当isDisplayed为true时渲染按钮 if habit.isDisplayed { Button(action: { print(habit.habitName + " button tapped") print(habit.isDisplayed ? "Yes" : "No") }) { Image("egg_uncracked") .resizable() .frame(width: 120, height: 120) } .supportsLongPress { habit.isDisplayed = false print(habit.habitName + " button held") } } } }
方式2:在ContentView中过滤已隐藏的Habit
在ContentView的ForEach中只遍历isDisplayed == true的元素,让隐藏的按钮直接从列表中移除:
// 修改ContentView中ScrollView部分代码 ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: -10) { if numOfEggs == 0 { Text("oops") } else { // 过滤出需要显示的habit ForEach($habits.filter({ $0.isDisplayed })) { $habit in HabitEggButton(habit: $habit) } } } } .offset(x: 25)
补充说明
你的@State和@Binding使用逻辑是正确的:ContentView中的@State var habits作为数据源,通过$habits传递给ForEach,再通过$habit绑定到HabitEggButton的@Binding var habit,状态传递链路完全通畅。之前视图未更新,只是因为没有把isDisplayed的变化映射到视图的显示逻辑上,SwiftUI无法感知到需要重渲染这部分内容。
内容的提问来源于stack exchange,提问作者Jesse Tzo
相关产品推荐
相关产品推荐

