UserDefaults疯狂,用DatePicker取2 [英] UserDefaults insanity, take 2 with a DatePicker

查看:87
本文介绍了UserDefaults疯狂,用DatePicker取2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于基本UserDefaults的先前帖子之后,正在进行SwiftUI中UserDefaults疯狂的进展基本上暴露了需要在UserDefaults值周围使用String()包装器...

Progressing on UserDefaults insanity in SwiftUI, after a previous post on basic UserDefaults which basically exposed the need to use a String() wrapper around UserDefaults values...

我现在对数据流感到沮丧:

I am now stomped by the data flow :

这个想法是提供一个DatePicker,设置为首次启动时在AppDelegate中注册的UserDefaults值. 随后,用户选择另一个设置为UserDefaults的日期. 但是,每次我在杀死"应用程序后启动该应用程序(即从应用程序切换器中向上滑动)时,选择器都会显示当前日期,而不是最后一个保存在UserDefaults中的日期.

The idea is to present a DatePicker, set to a UserDefaults value registered in AppDelegate on first launch. Subsequently, the user picks another date that is set to the UserDefaults. But every time I launch the app after having "killed" it (i.e swiped up from app switcher), the Picker displays the present date and NOT the one last saved in UserDefaults.

此外,我在选择器的上方和下方显示一些文本,以尝试理解数据流,但如果有人有时间给它一个日期,似乎日期显示存在一步滞后的情况.尝试,这是代码:

Also, I display some texts above and below the picker to try and make sense of the data flow, but it seems that there is a one step lag in the displaying of the dates, if anyone has the time to give it a try, here is the code :

1-在AppDelegate中,我注册了我的初始UserDefaults(就像我在UIKit中一样):

1- In AppDelegate, I register my initial UserDefaults (like I always did in UIKit) :

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch
        UserDefaults.standard.register(defaults: [
        "MyBool 1": true,
        "MyString": "Soo",
        "MyDate": Date()
        ])

        return true
    }

2-在ContentView中,我尝试显示它们:

2- in ContentView, I try to display them :

import SwiftUI

struct ContentView: View {

    let defaults = UserDefaults.standard

    var dateFormatter: DateFormatter {
     let formatter = DateFormatter()
    // formatter.dateStyle = .long
     formatter.dateFormat = "dd MMM yy"
     return formatter
     }

    @State var selectedDate = Date()

    init() {
        self.loadData() // This should set "selectedDate" to the UserDefaults value
    }

    var body: some View {

        VStack {
            Text("The BOOL 1 value is : Bool 1 = \(String(defaults.bool(forKey: "MyBool 1")))")
            Divider()
            Text("My string says : \(String(defaults.string(forKey: "MyString")!))")
            Divider()
            Text("The date from UserDefaults is : \(dateFormatter.string(from: defaults.object(forKey: "MyDate") as! Date))")
            Divider()
            DatePicker(selection: $selectedDate, label: { Text("") })
                .labelsHidden()
                .onReceive([self.selectedDate].publisher.first()) { (value) in
                    self.saveDate()
                }

            Divider()
            Text("The chosen date is : \(selectedDate)")
        }
    }

    func loadData() {
        selectedDate = defaults.object(forKey: "MyDate") as! Date
        print("----> selected date in \"init\" from UserDefaults: \(dateFormatter.string(from: selectedDate) )) ")
    }

    private func saveDate() { // This func is called whenever the Picker sends out a value
        UserDefaults.standard.set(selectedDate, forKey: "MyDate")
        print("Saving the date to User Defaults : \(dateFormatter.string(from: selectedDate) ) ")
    }

}

任何帮助将不胜感激!

推荐答案

这是我的第二个答案,如果您也想更新文本,那不是不错",当然不是最好的方法,但是可行(我已经测试过了)

here is my 2nd answer, if you want to update the text also...it is not "nice" and for sure not the best way, but it works (i have tested it)

struct ContentView: View {

    let defaults = UserDefaults.standard

    var dateFormatter: DateFormatter {
     let formatter = DateFormatter()
    // formatter.dateStyle = .long
     formatter.dateFormat = "dd MMM yy"
     return formatter
     }
    @State var uiUpdate : Int = 0
    @State var selectedDate : Date
    @State var oldDate : Date = Date()

    init() {
        _selectedDate = State(initialValue: UserDefaults.standard.object(forKey: "MyDate") as! Date) // This should set "selectedDate" to the UserDefaults value
    }

    var body: some View {

        VStack {
            Text("The BOOL 1 value is : Bool 1 = \(String(defaults.bool(forKey: "MyBool 1")))")
            Divider()
            Text("My string says : \(String(defaults.string(forKey: "MyString")!))")
            Divider()
            Text("The date from UserDefaults is : \(dateFormatter.string(from: defaults.object(forKey: "MyDate") as! Date))")
                .background(uiUpdate < 5 ? Color.yellow : Color.orange)
            Divider()
            DatePicker(selection: $selectedDate, label: { Text("") })
                .labelsHidden()
                .onReceive([self.selectedDate].publisher.first()) { (value) in
                    if self.oldDate != value {
                        self.oldDate = value
                        self.saveDate()
                    }
                }

            Divider()
            Text("The chosen date is : \(selectedDate)")
        }
    }

    func loadData() {
        selectedDate = defaults.object(forKey: "MyDate") as! Date
        print("----> selected date in \"init\" from UserDefaults: \(dateFormatter.string(from: selectedDate) )) ")
    }

    private func saveDate() { // This func is called whenever the Picker sends out a value
        UserDefaults.standard.set(selectedDate, forKey: "MyDate")
        print("Saving the date to User Defaults : \(dateFormatter.string(from: selectedDate) ) ")
        uiUpdate = uiUpdate + 1
    }

}

这篇关于UserDefaults疯狂,用DatePicker取2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆