午夜后刷新iOS UIDatePicker的内部状态

chb*_*own 9 iphone uidatepicker uikit ios swift

我正在编写一个iPhone应用程序(Swift 4.0,iOS 10.3.3,Xcode 9.2),UIViewController其中包含一个主UIDatePicker模式,其默认模式为默认模式UIDatePickerMode.dateAndTime.用户旨在使应用程序在后台运行(尽管这不是必需的),并且有时打开它,选择特定的日期和时间,然后单击按钮.

我的问题是,当应用程序在最初启动后的一天(或几天)重新打开时,微调器的日期部分上的时间敏感标签,即"今天"和"昨天",不会得到更新.留在后台.

这意味着,在使用一天左右后,UI可能会处于混乱或不一致状态.例如,这是1月19日的截图:

带有错误

它设法将"昨天"线重新描绘为"1月17日星期三",但没有将"今天"改为"昨天"或"1月19日星期五"为"今天".

另一个,从今天中午1月22日中午左右开始(选定的值是1月21日上午9点29分):

带有错误

"昨天"是正确的,但"今天"不见了.

有时陈旧的标签就会堆积起来,就像1月14日这个镜头一样(选定值是1月15日10:47 PM):

带有多个陈旧

如果我强制退出并重新启动应用程序,一切看起来都是新鲜和正确的,但我想避免这样做.

我试着打电话setNeedsDisplay()UIDatePicker时候实例viewWillAppear被调用,以及一旦NotificationCenter触发.UIApplicationWillEnterForeground事件,但没有成功:(.

大多数控件没有内部状态,这取决于当前时间,所以我想这不会经常出现.但在这种情况下,我的选择是什么?

如何触发UIDatePicker控件的完全刷新?


SO上似乎有三个类似的问题:


编辑:现在是1月23日,午夜过后5分钟.我试过了什么:

  1. setNeedsDisplay()每当视图出现/应用程序进入前景时调用UIDatePicker(我将在"刷新时"调用它).上面的观察/截图都是在这种情况下拍摄的.在我添加之前我遇到了同样的问题setNeedsDisplay(),我没有注意到行为的任何变化,但在添加之前我并没有那么分析.陈旧标签是有和没有的问题setNeedsDisplay().
  2. .date = ...直接在"刷新时" 设置字段(使用与viewDidLoad最初调用时相同的存储日期).这没有直接影响(目前的日期是1月23日):

    带有错误

    但更新了底层(?!)(这里我主动中间滚动):

  3. 我实际上在同一个视图上有两个UIDatePickers,所以我也可以通过测试设置日期.setDate(..., animated: true),效果好一点 - "1月22日"成为"昨天",但没有"今天"日期("Jan" 23"遗骸"1月23日"):

    爆炸新闻!大约30分钟后(上午12:35),在重新开启应用程序并重新打开应用程序后,标签再次发生变化.在.date直接设置(2.)的情况下,"今天"现在在两个层上出现并且是正确的.使用.setDate(...)(3.),"今天"已正确应用,但昨天(在灰色图层上)也是"今天".

    我猜它一定是因为,在上午12:05(再次)设置呼叫之后,我滚动了一点,然后就在现在,在12:30 AM,再次触发了日期设置呼叫?但这只是一个想法 - 滚动似乎甚至在实时中有一些奇怪的副作用.

  4. (截至1月24日)设置(一次,初始化时)myDatePicker.locale = NSLocale.autoupdatingCurrent(默认为NSLocale.current).这似乎没有效果:"今日"标签在"刷新"时仍然是错误的.
  5. (截至1月25日)尝试(4.)与(1.)结合.没有骰子.
  6. 通话picker.becomeFirstResponder()和/或picker.reloadInputViews()"刷新".似乎没有任何影响.

Leo*_*bus 8

我不认为你今天和昨天都可以在你的日期选择器中显示,但你可以正确地将你的日期选择器更新从Superview中删除并重新设置它.顺便说一下,你可以为NSCalendarDayChanged你的视图控制器添加一个观察者,并添加一个选择器来创建一个新的日期选择器:

class ViewController: UIViewController {
    var datePicker = UIDatePicker()
    var date = Date()
    override func viewDidLoad() {
        super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(dayChanged), name: .NSCalendarDayChanged, object: nil)
        setupDatePicker()
    }
    func setupDatePicker() {
        DispatchQueue.main.async {
            self.datePicker.removeFromSuperview()
            self.datePicker = UIDatePicker()
            self.datePicker.addTarget(self, action: #selector(self.datePickerChanged), for: .valueChanged)
            self.datePicker.datePickerMode = .dateAndTime
            self.datePicker.date = self.date
            self.view.addSubview(self.datePicker)
        }
    }
    @objc func datePickerChanged(_ datePicker: UIDatePicker) {
        print("datePicker.date:", datePicker.date)
        date = datePicker.date
    }
    @objc func dayChanged(_ notification: Notification) {
        print("day changed:", Date().description(with: .current))
        setupDatePicker()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿Leo快乐100K!对不起,我错过了 (4认同)
  • 很好,我不知道`NSCalendarDayChanged`.如果没有更简单的解决方案,那将成为我解决方法的一部分. (3认同)