Help us understand the problem. What is going on with this article?

UIDatePickerのバグ?

More than 3 years have 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
}

これで直った。

おしまい

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

fuzzball
つい出来心で。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away