Edited at

UIDatePickerのバグ?

More than 1 year has passed since last update.


検証コード

iOS 9.3.3 + Swift 2

class ViewController: UIViewController {

let datePicker = UIDatePicker()

override func viewDidLoad() {
super.viewDidLoad()

datePicker.datePickerMode = .Date
datePicker.center = self.view.center
datePicker.date = NSDate(timeIntervalSince1970: 0)
self.view.addSubview(datePicker)
}

override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
print(datePicker.date)
}
}


西暦 → 和暦


起動時

1970-01-01 00:00:00 +0000

西暦


和暦に変更


  • 変更前にDatePickerを触らない

1970-01-01 00:00:00 +0000

触らず和暦

年がおかしい。(正しくは昭和45年)

月と日がグレーになっている。


  • 変更前にDatePickerを触る(ちょっとズラして元に戻す)

2619-01-01 00:00:00 +0000

触って和暦

.dateが変更されている。

年がおかしい。(正しくは平成631年)

月と日がグレーになっている。


和暦 → 西暦


起動時

1970-01-01 00:00:00 +0000

和暦


西暦に変更


  • 変更前にDatePickerを触らない

1970-01-01 00:00:00 +0000

触らず西暦

年がおかしい。(正しくは1970年)


  • 変更前にDatePickerを触る(ちょっとズラして元に戻す)

0044-12-31 23:41:01 +0000

触って西暦

.dateが変更されている。

年がおかしい。というか西暦44年は表示できない。


対策


autoupdatingCurrent...()

datePicker.locale = NSLocale.autoupdatingCurrentLocale()

datePicker.calendar = NSCalendar.autoupdatingCurrentCalendar()
datePicker.calendar.locale = NSLocale.autoupdatingCurrentLocale()

DatePickerの表示がおかしいのはちょっと直った。(一部グレー化のみ)


LocaleとCalendarの再設定

viewWillLayoutSubviews()の中でLocaleとCalendarを再設定。

datePicker.locale = NSLocale.currentLocale()

datePicker.calendar = NSCalendar.currentCalendar()

DatePickerの表示がおかしいのは直った。(1年ずれと一部グレー化)

.dateが変更されるのは直らない。


dateを保存しておいて再設定する

valueChanged()で保存しておいて、viewWillLayoutSubviews()で再設定。

var latestDate = NSDate(timeIntervalSince1970: 0)

override func viewDidLoad() {
:
datePicker.addTarget(self, action: #selector(ViewController.valueChanged(_:)), forControlEvents: .ValueChanged)
:
}

override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//再設定
datePicker.locale = NSLocale.currentLocale()
datePicker.calendar = NSCalendar.currentCalendar()
datePicker.date = latestDate
}

func valueChanged(sender: UIDatePicker) {
//保存
latestDate = sender.date
}

これで直った。


おしまい

標準アプリでもおかしくなる。(リマインダーとヘルスケアで確認)

どうもバグくさい。