【问题标题】:Refresh internal state of iOS UIDatePicker after midnight午夜后刷新 iOS UIDatePicker 的内部状态
【发布时间】:2018-01-23 00:53:10
【问题描述】:

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

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

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

它设法将“昨天”行重绘为“1 月 17 日星期三”,但没有将“今天”渲染为“昨天”,或将“1 月 19 日星期五”渲染为“今天”。

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

“昨天”是正确的,但缺少“今天”。

有时陈旧的标签会堆积如山,例如 1 月 14 日的这张照片(选择的值是 1 月 15 日晚上 10:47):

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

每当调用viewWillAppear 以及每当NotificationCenter 触发.UIApplicationWillEnterForeground 事件时,我都尝试在UIDatePicker 实例上调用setNeedsDisplay(),但无济于事:(。

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

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


似乎已经有关于 SO 的三个类似问题:


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

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

    但更新了底层(?!)(这里我正在积极中滚动):

  3. 我实际上在同一个视图上有两个 UIDatePickers,所以我也可以通过.setDate(..., animated: true) 测试设置日期,效果更好一些——“1 月 22 日”变成了“昨天”,但没有“ Today”日期(“Jan 23”仍然是“Jan 23”):

    重大新闻!约 30 分钟后(上午 12 点 35 分),在后台运行并再次重新打开应用程序后,标签再次更改。在直接设置.date (2.) 的情况下,“今天”现在出现并且在两个层上都是正确的。使用.setDate(...) (3.),“今天”已正确应用,但昨天(在灰色图层上)也是“今天”。

    我猜这一定是因为,在上午 12:05 日期(重新)设置电话之后,我滚动了一点,然后刚刚在上午 12:30,再次触发了日期设置电话?但这只是一个想法——即使是实时滚动似乎也会产生一些奇怪的副作用。

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

【问题讨论】:

  • 用您迄今为止尝试过的代码更新您的问题以使其工作。

标签: ios iphone swift uikit uidatepicker


【解决方案1】:

我认为您不能在日期选择器中同时显示今天和昨天,但您可以让您的日期选择器正确更新,将其从 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()
    }
}

【讨论】:

  • 嘿,Leo 快乐 100K!对不起,我错过了
  • 很好,我不知道NSCalendarDayChanged。如果没有更直接的解决方案,那将是我解决方法的一部分。 ?
猜你喜欢
  • 2023-03-19
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2021-08-08
  • 2021-01-25
相关资源
最近更新 更多