0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOS14でdatePickerが特定の分刻みにならない

Posted at

こんばんは、iOSエンジニアの奥江です。
少しばかり苦戦したところを共有したいと思います。

問題

datePickerを5分刻みの時間を設定して時間を取得してもLabelに反映される時間が5分刻みの時間になりませんでした。

原因

iOS14まではroundsToMinuteIntervalが無効なことが原因でした。ドキュメントをもっと読まないとダメですね、、:frowning2:
https://developer.apple.com/documentation/uikit/uidatepicker/3791478-roundstominuteinterval

解決方法

iOS14でも5分(ここは適当な数字を設定できます)刻みで取得できるようにしたいと思います。
今回はTextFieldをタップしたらdatePickerを表示して時間と分を取得するようにします。

viewController

class ViewController: UIViewController {
    
    @IBOutlet weak var textField: UITextField!
    
    let datePicker = UIDatePicker()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        createToolBar()
        prepareSetting()
    }
    
    private func createToolBar() {
        let toolBar = UIToolbar()
        let doneButton = UIBarButtonItem(title: "完了",
                                         style: .done,
                                         target: nil,
                                         action: #selector(doneButtonDidTap))
        let cancellButton = UIBarButtonItem(title: "キャンセル",
                                            style: .plain,
                                            target: nil,
                                            action: #selector(cancellButtonDidTap))
        let specer = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace,
                                     target: nil,
                                     action: nil)
        toolBar.setItems([cancellButton, specer, doneButton], animated: false)
        toolBar.sizeToFit()
        textField.inputAccessoryView = toolBar
    }

    private func prepareSetting() {
        // datePickerを5分刻みにする
        datePicker.minuteInterval = 5
        // 時間表示にする
        datePicker.datePickerMode = .time
        // スタイルをドラム式にする
        datePicker.preferredDatePickerStyle = .wheels
        // textFieldにdatePickerをセット
        textField.inputView = datePicker
        // textFieldのdelegate先をselfにする
        textField.delegate = self
    }
    
    @objc
    private func doneButtonDidTap() {
        // iOS 15.0以上の時はそのまま返す。15.0以下だと四捨五入して返す
        let date: Date = {
            if #available(iOS 15.0, *) {
                return datePicker.date
            } else {
                return datePicker.date.roundsToMinuteIntervalDate()
            }
        }()
        textField.text = date.dateToString()
        view.endEditing(true)
    }
    
    @objc
    private func cancellButtonDidTap() {
        view.endEditing(true)
    }
}

extension ViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
       textField.endEditing(true)
        return true
    }
}

extension

extension Date {
    // dateをStringに変換する
    func dateToString() -> String {
        let dateFormat = DateFormatter()
        dateFormat.dateFormat = "HH:mm"
        return dateFormat.string(from: self)
    }
    
    // 時間と分を取得して分を四捨五入し新たなDateを返す
    // 5分刻みの場合の計算
    func roundsToMinuteIntervalDate() -> Date {
        let calender = Calendar(identifier: .gregorian)
        let hour = Calendar.appCalender.component(.hour, from: self)
        let minute = Calendar.appCalender.component(.minute, from: self)

        // minuteが5で割り切れない場合はそのままの分を返す
        let roundMinute: Int = {
            if minute % 5 == 0 {
                return minute
            } else {
                return (5 - minute % 5) + minute
            }
        }()
        return calender.date(from: DateComponents(hour: hour, minute: roundMinute)) ?? Date()
    }
}
extension Calendar {
    static var appCalender: Calendar = {
        var calender = Calendar(identifier: .gregorian)
        calender.timeZone = TimeZone(identifier: "Asia/Tokyo")!
        calender.locale = Locale(identifier: "ja_JP")
        return calender
    }()
}

こんなことあんまりしないと思いますが、参考までにどうぞ:relaxed:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?