微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

仅在应用程序首次加载时将视图参数传递给视图-SwiftUI

如何解决仅在应用程序首次加载时将视图参数传递给视图-SwiftUI

我有一个导航视图(SettingsView),如下所示。当我第一次进入Pay​​ScheduleForm时,UserDefaults中的日期会正确传递。如果更改PayScheduleForm中的payDate值,则可以看到它正确更新了UserDefaults键。但是,如果我返回到SettingsView,然后再次转到PayScheduleForm,则原始值仍会显示在选择器中。

这是一个奇怪的情况,所以也许最好一步一步地解释一下:

  1. 启动应用
  2. 转到“设置”->“付款时间表”
  3. 最后一个UserDefaults的payDate值位于DatePicker(10/08/2020)
  4. 将值更改为10/14/2020-控制台显示字符串UserDefaults.standard.object(forKey:“ payDate”)= 10/14/2020
  5. 返回设置(使用“后退”按钮)
  6. 返回“付款时间表”,查看DatePicker的原始值(2020年10月8日)
  7. 当然,如果我再次重新启动应用程序,我会在DatePicker中看到2020年10月14日
struct SettingsView: View {

    
    var body: some View {
        NavigationView{
            if #available(iOS 14.0,*) {
                List{
                    NavigationLink(destination: AccountsList()) {
                        Text("Accounts")
                    }
                    NavigationLink(destination: CategoriesList()) {
                        Text("Categories")
                    }
                    NavigationLink(destination: PayScheduleForm(date: getPayDate()).onAppear(){
                        getPayDate()
                        
                    }) {
                        
                        Text("Pay Schedule")
                    }
                }.navigationTitle("Settings")
            } else {
                // Fallback on earlier versions
            }
            
        }.onAppear(perform: {
            getUserDefaults()
        })
    }
    
    func getPayDate() -> Date{
        var date = Date()
        if UserDefaults.standard.object(forKey: "payDate") != nil {
            date = UserDefaults.standard.object(forKey: "payDate") as! Date
        }
        let df = DateFormatter()
        df.dateFormat = "MM/dd/yyyy"
        print(df.string(from: date))
        
        return date
    }
struct PayScheduleForm: View {
    var frequencies = ["Bi-Weekly"]
    
    @Environment(\.managedobjectContext) var context
    
    
    @State var payFrequency: String?
    @State var date: Date
    
    var nextPayDay: String{
        let nextPaydate = (Calendar.current.date(byAdding: .day,value: 14,to: date ))
        return Utils.dateFormatterMed.string(from: nextPaydate ?? Date() )
    }
    var body: some View {
        Form{
            Picker(selection: $payFrequency,label: Text("Pay Frequency")) {
                if #available(iOS 14.0,*) {
                    ForEach(0 ..< frequencies.count) {
                        Text(self.frequencies[$0]).tag(payFrequency)
                    }.onChange(of: payFrequency,perform: { value in
                        UserDefaults.standard.set(payFrequency,forKey:"payFrequency")
                        print(UserDefaults.standard.string(forKey:"payFrequency")!)
                    })
                } else {
                    // Fallback on earlier versions
                }
                }
            if #available(iOS 14.0,*) {
                DatePicker(selection: $date,displayedComponents: .date) {
                    Text("Last Payday")
                }
                
                .onChange(of: date,perform: { value in
                    UserDefaults.standard.set(date,forKey: "payDate")
                    let date = UserDefaults.standard.object(forKey: "payDate") as! Date
                    let df = DateFormatter()
                    df.dateFormat = "MM/dd/yyyy"
                    print(df.string(from: date))
                })
            } else {
                // Fallback on earlier versions
            }
            
            
            
        }
    ```

解决方法

解决了这个问题。发表帖子,以便其他遇到相同问题的人都能找到答案。

iOS 14允许使用@AppStorage属性包装器,该包装器可以轻松访问UserDefaults,但截至目前,@ AppStorage不允许使用Date类型。

相反,您可以使用@Observable对象

首先创建一个名为UserSettings.swift的swift文件,并在其中创建一个类:

for line in stdout:
    sys.stdout.write(line)

然后在您的视图中添加一个@ObservableObject

class UserSettings: ObservableObject {
    @Published var date: Date {
        didSet {
            UserDefaults.standard.set(date,forKey: "payDate")
        }
    }
    
    init() {
        self.date = UserDefaults.standard.object(forKey: "payDate") as? Date ?? Date()
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。