【问题标题】:UserDefault value does not update in a list SwiftUIUserDefault 值不会在 SwiftUI 列表中更新
【发布时间】:2021-01-25 08:04:16
【问题描述】:

我有两个视图,嵌入在 TabView 中。 我在一个名为 usersettings 的类中使用 userdefaults。

class UserSettings: ObservableObject {
    @Published var favList: [String] {
        willSet {
            print("willset")
        }
        didSet {
            UserDefaults.standard.set(favList, forKey: "isAccountPrivate")
            print("didset")
        }
    }
    init() {
        self.favList = UserDefaults.standard.object(forKey: "isAccountPrivate") as? [String] ?? ["Sepetiniz Boş"]
    }
}

在按钮视图中,其作用类似于添加/删除收藏夹。它成功地从 UserDefaults 添加和删除。但是当我添加一些东西时,它不会显示在另一个视图上(请参阅 FavButton 之后的下一个代码)

struct FavButton: View {
    
    @Binding var passedFood: String
    @ObservedObject var userSettings = UserSettings()

    var body: some View {

        Button(action: {
            if userSettings.favList.contains(passedFood) {
                userSettings.favList.remove(at: userSettings.favList.firstIndex(of: passedFood )!)
            } else {
                
                userSettings.favList.append(passedFood)
                
            }
            
        })  
        
    }
}

但除非我关闭并打开我的应用程序,否则它不会在其他视图中更新我的列表。如果我从列表中删除某些内容,它实际上会从 userdefault 中删除。

如果我在这个视图中添加一个新词,它也可以工作。

我唯一的问题是,当我从另一个视图 (FavButton) 添加某些内容时,它不会显示在此视图 (FavView) 中。

struct FavView: View {
    
    @ObservedObject var userSettings = UserSettings()
    @State private var newWord = ""

    var body: some View {
        
        NavigationView {
            List {
                TextField("Ürün Ekleyin...", text: $newWord, onCommit: addNewWord)
                ForEach( self.userSettings.favList, id: \.self) { list in
                    Text(list)
                        .font(.headline)
                        .padding()
                    
                }
                .onDelete(perform: self.deleteRow)
            }
            .navigationTitle("Sepetim")
        }
    }
    
    private func deleteRow(at indexSet: IndexSet) {
        
        self.userSettings.favList.remove(atOffsets: indexSet)
    }
    
    private func addNewWord() {
        let answer = newWord.lowercased().trimmingCharacters(in: .whitespacesAndNewlines)
        self.userSettings.favList.append(answer)
        guard answer.count > 0 else {
            return
        }
        newWord = ""
    }
    
}

【问题讨论】:

    标签: swift swiftui nsuserdefaults


    【解决方案1】:

    遵循 SwiftUI 习惯用法的更好方法是使用 .environmentObject() 修饰符。

    当你声明你的应用时:

    struct AppScene: App {
    
      @StateObject private var userSettings = UserSettings() // Use state object to persist the object
    
      var body: some Scene {
        WindowGroup {
          ContentView()
            .environmentObject(userSettings) // Inject userSettings into the environment 
        }
      }
    }
    

    然后在你ContentView 中你可以进入你的环境并获取对象:

    struct ContentView: View {
      @EnvironmentObject private var userSettings: UserSettings
      var body: some View {
        Text("Number of items in favList: \(userSettings.favList.count)")
      }
    }
    

    【讨论】:

    • 有时候确实更好,但是 EnvironmentObject 只能在 SwiftUI 视图层次结构中工作,所以你不能与 UIKit 视图、其他类共享它,并且需要记住在不同的 SwiftUI 视图层次结构之间重新注入......所以有很多陷阱。请注意。
    【解决方案2】:

    您需要在要观察用户设置的所有视图中使用UserSettings 的相同实例,例如

    class UserSettings: ObservableObject {
       static let global = UserSettings()
    //... other code
    }
    

    现在

    struct FavButton: View {
        @ObservedObject var userSettings = UserSettings.global    // << here !!
    
    // ... other code
    }
    

    struct FavView: View {
        @ObservedObject var userSettings = UserSettings.global   // << here !!
    
    // ... other code
    }
    

    【讨论】:

    • 谢谢!我还不知道变量 global 是如何连接到 usersettings 中的 Published 变量的。但效果很好。
    猜你喜欢
    • 2020-03-14
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多