【问题标题】:It does not read that the setting has changed它没有读取设置已更改
【发布时间】:2021-11-26 21:49:16
【问题描述】:

我有一个问题,我更改了“SettingView”中的“isDynamic”设置,然后退出设置窗口,“SongbookView”没有记录设置已更改。我想根据设置中选择的选项更改搜索引擎。造成这种情况的原因是什么?

歌本视图:

import CoreData
import SwiftUI

struct SongbookView: View {
    @State var searchText: String = ""
    @State var isSettings: Bool
    @ObservedObject var userSettings: UserSettings = UserSettings()
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(
        entity: Song.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Song.number, ascending: true)]
    ) var songs: FetchedResults<Song>
    
    var body: some View {
        NavigationView{
            VStack{
                if userSettings.isDynamic == false {
                    SearchBar(text: $searchText)
                } else {
                    DynamicSearchBar(text: $searchText)
                }
                List(songs.filter({searchText.isEmpty ? true : removeNumber(str: $0.content!.lowercased()).contains(searchText.lowercased()) || String($0.number).contains(searchText)}), id:\.objectID) { song in
                    NavigationLink(destination: DetailView(song: song, isSelected: song.favorite)) {
                        HStack{
                            Text("\(String(song.number)). ") .font(.headline) + Text(song.title ?? "Brak tytułu")
                            if song.favorite {
                                Spacer()
                                Image(systemName: "heart.fill")
                                    .accessibility(label: Text("To jest ulubiona pieśń"))
                                    .foregroundColor(.red)
                            }
                        }.lineLimit(1)
                    }
                }.id(UUID())
                    .listStyle(InsetListStyle())
            }
            .padding(.top, 10)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .principal) {
                    HStack{
                        Text(String(self.userSettings.isDynamic))
                        Spacer()
                        Text("Śpiewnik")
                            .font(.system(size: 20))
                            .bold()
                        Spacer()
                        Button(action: {
                            isSettings.toggle()
                            print(userSettings.isDynamic)
                        }) {
                            Image(systemName: "gearshape")
                                .resizable()
                                .frame(width: 16.0, height: 16.0)
                        }
                        .sheet(isPresented: $isSettings) {
                            SettingView(isPresented: $isSettings)
                                }
                    }
                }
            }
        }
    }
    
    func removeNumber(str: String) -> String {
        var result = str
        let vowels: Set<Character> = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
        result.removeAll(where: { vowels.contains($0) })
        return result
    }
}

设置视图:

import SwiftUI

struct SettingView: View {
    @ObservedObject var userSettings = UserSettings()
    @Binding var isPresented: Bool
    var body: some View {
        NavigationView {
            Form {
                Toggle("Dynamiczna wyszukiwarka", isOn: $userSettings.isDynamic)
                    .onChange(of: userSettings.isDynamic) { value in
                        print(value)
                    }
                Button(action: {
                    print(userSettings.isDynamic)
                    isPresented = false
                }) {
                    Text("Test")
                }
            }
            .navigationBarTitle("Ustawienia")
        }
    }
}

用户设置:

import Foundation
import Combine

class UserSettings: ObservableObject {
    @Published var isDynamic: Bool {
        didSet {
            UserDefaults.standard.set(isDynamic, forKey: "isSearchDynamic")
        }
    }
    
    init() {
        self.isDynamic = UserDefaults.standard.object(forKey: "isSearchDynamic") as? Bool ?? false
    }
}

【问题讨论】:

    标签: swiftui settings


    【解决方案1】:

    您正在使用UserSettings 的两个不同实例。当您在这些实例中的一个上更新isDynamic 时,另一个,即使它引用了UserDefaults,也没有理由知道它需要更新。

    这里最简单的解决方案是共享UserSettings 的单个实例:

    struct SongbookView: View {
        @State var searchText: String = ""
        @State var isSettings: Bool
        @ObservedObject var userSettings: UserSettings = UserSettings()
        @Environment(\.managedObjectContext) var managedObjectContext
        @FetchRequest(
            entity: Song.entity(),
            sortDescriptors: [NSSortDescriptor(keyPath: \Song.number, ascending: true)]
        ) var songs: FetchedResults<Song>
        
        var body: some View {
            //...
            .sheet(isPresented: $isSettings) {
              SettingView(userSettings: userSettings,isPresented: $isSettings)
            }
            //...
        }
    }
    
    struct SettingView: View {
        @ObservedObject var userSettings : UserSettings
        @Binding var isPresented: Bool
        var body: some View {
            //...
        }
    }
    

    您还可以查看 @AppStorage (https://www.hackingwithswift.com/quick-start/swiftui/what-is-the-appstorage-property-wrapper) 之类的属性包装器,它们实际上会在 UserDefaults 值更改时动态更新。

    【讨论】:

    • 这回答了你的问题吗?
    猜你喜欢
    • 2020-09-04
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 2020-02-14
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    相关资源
    最近更新 更多