将视图作为参数传入另一视图时@AppStorage无法更新问题问询
SwiftUI中@AppStorage作为视图参数传递时的更新问题
问题复现
我定义了一个接收视图作为参数的ListItem视图:
struct ListItem<Content: View>: View { let title: String let suffix: () -> Content // 接收视图 var body: some View { HStack { Text(title) Spacer() suffix() // 渲染传入的视图 } } }
接着我把包含动态@AppStorage内容的视图传入其中:
struct MyList: View { @AppStorage("counter") var counter: Int = 0 // 绑定UserDefaults中的值 var body: some View { ListItem(title: "Counter") { Text("\(counter)") // 传入带@AppStorage绑定的文本视图 } Button("Increment") { counter += 1 // 修改UserDefaults中的值 } } }
此时点击"Increment"按钮,ListItem里显示的数值不会实时更新——只有当视图触发重渲染(比如子视图刷新、onAppear触发)时,才会显示新值。但如果用@State或@Environment绑定的值,就不会出现这个问题。
疑问
这是@AppStorage的预期行为还是Bug?还有哪些传递视图参数的场景会导致状态过期?
解决方法
我尝试用ViewModifier实现了相同的布局逻辑:
struct ListItemizer: ViewModifier { let title: String func body(content: Content) -> some View { HStack { Text(title) Spacer() content // 渲染原视图 } } }
然后把这个修饰符应用到包含动态内容的视图上:
struct MyList: View { @AppStorage("counter") var counter: Int = 0 var body: some View { Text("\(counter)") .modifier( ListItemizer(title: "Counter") // 为带动态绑定的文本视图添加修饰符 ) Button("Increment") { counter += 1 } } }
这时点击按钮,数值会立即更新,符合预期。
内容的提问来源于stack exchange,提问作者Andriy Gordiyenko
相关产品推荐
相关产品推荐

