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

SwiftUI中孙视图更新后如何实时刷新主视图图片?

SwiftUI三层视图状态同步问题解决

三层SwiftUI视图结构中,点击第三层ExLibrisCategoryItem的图片后,顶层ExLibrisStyleView的选中图标无法实时更新,只有关闭重开页面才会生效。核心问题是iconValue的@State和@Binding使用错误,导致状态无法在视图间同步。

错误原因

  • 顶层ExLibrisStyleView中,iconValue用@State初始化时仅从UserDefaults读取一次,后续UserDefaults变化不会触发视图刷新;且传递给子视图时是传值而非绑定,子视图修改的是独立副本,无法同步回顶层。
  • 中间层ExLibrisCategoryRow错误地用@State声明iconValue,应该用@Binding接收顶层的状态绑定,才能将子视图的修改同步回去。

修正方案

  1. 顶层改用@AppStorage替代@State,它会自动同步UserDefaults的变化,同时具备@State的视图刷新能力。
  2. 传递iconValue时使用绑定语法$iconValue,确保子视图能修改顶层的状态。
  3. 中间层ExLibrisCategoryRow将@State var iconValue改为@Binding var iconValue,接收顶层的绑定并传递给第三层。
  4. 第三层ExLibrisCategoryItem的点击事件直接修改绑定的iconValue,@AppStorage会自动将值保存到UserDefaults,无需手动调用UserDefaults.set。

修正后的ExLibrisStyleView视图

import SwiftUI

struct ExLibrisStyleView: View {
    @EnvironmentObject var exlibrisData: ExLibrisModelData
    // 用@AppStorage替代@State,自动同步UserDefaults并触发视图刷新
    @AppStorage("iconValue") var iconValue: String = "exlibris-0"
    
    var body: some View {
        NavigationView{
            List {
                VStack(alignment: .leading) {
                    Text("Selected Bookmark")
                        .font(.headline)
                        .padding(.bottom,15)
                    
                    Image(iconValue)
                        .renderingMode(.original)
                        .resizable()
                        .frame(width: 130, height: 130)
                        .cornerRadius(5)
                        .shadow(color: Color(red:0, green:0, blue:0, opacity:0.25), radius: 8, x: 0, y: 0)
                }
                .padding(.leading, 15)
                .padding(.bottom,30)
                .listStyle(.inset)
                .listRowInsets(EdgeInsets())
                
                ForEach(exlibrisData.categories.keys.sorted(), id: \.self) { key in
                    // 传递绑定给子视图
                    ExLibrisCategoryRow(categoryName: key, items: exlibrisData.categories[key]!, iconValue: $iconValue)
                }
                .listRowInsets(EdgeInsets())
            }
            .listStyle(.inset)
            .navigationTitle("Bookmark Collection")
        }
    }
}

修正后的ExLibrisCategoryRow视图

import SwiftUI
struct ExLibrisCategoryRow: View {
    var categoryName: String
    var items: [ExLibris]
    // 用@Binding接收顶层的状态绑定
    @Binding var iconValue: String
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(categoryName)
                .font(.headline)
                .padding(.leading, 15)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(alignment: .top, spacing: 0) {
                    ForEach(items) { exlibris in
                        label: do {
                            // 传递绑定给第三层视图
                            ExLibrisCategoryItem(exlibris: exlibris, iconValue: $iconValue)
                        }
                    }
                }
            }
            .frame(height: 200)
        }       
    }
}

修正后的ExLibrisCategoryItem视图

import SwiftUI

struct ExLibrisCategoryItem: View {
    var exlibris: ExLibris
    @Binding var iconValue: String
    
    var body: some View {
        VStack(alignment: .leading) {
            Image(exlibris.imageName)
                .renderingMode(.original)
                .resizable()
                .frame(width: 130, height: 130)
                .cornerRadius(5)
                .onTapGesture {
                    // 直接修改绑定的iconValue,@AppStorage会自动保存到UserDefaults
                    iconValue = exlibris.imageName
                }            
        }
        .padding(.leading, 15)
    }
}

内容的提问来源于stack exchange,提问作者baymak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:37:08