iOS
Swift

DatePickerをコードで作って画面遷移を早くしよう

最近「この画面遷移なぜか遅い...なぜだ...」と思い、真面目に調査したところ、

InterfaceBuilderで作成したDatePickerを持つPickerViewのnibのloadに

凄まじく時間がかかっていることが分かりました。

※画面遷移の遅さを調べるために参考にした記事

https://qiita.com/ken0nek/items/7577d26143a6fe4355f9


原因

正直、詳しい原因は分かりませんでした...

もし分かる人がいたら教えてください。m(_ _)m


対策: InterfaceBuilderを使わなければ良い!

UIDatePickerをコードのみで生成するようにしてしまえばよいのです!

この記事では、InterfaceBuilderで生成した場合とコードのみで生成した場合の

両方のコードを紹介しつつ、挙動がどれくらい違うかを示します。


InterfaceBuilderを利用してUIDatePickerを生成

コード: https://github.com/fuwamaki/function_confirm/tree/master/FunctionConfirm/Picker/NibPickerView

InterfaceBuilderを用いる場合は、こんな感じにxibファイルを生成して、

xibファイルに紐付いたクラスを設けて、

※NibLoadableは拡張クラス。


import UIKit

final class CustomPickerView: UIView {

@IBOutlet weak var datePickerView: UIDatePicker!

override func awakeFromNib() {
super.awakeFromNib()
}
}

extension CustomPickerView: NibLoadable {}

用いたいViewから参照して利用します。


func setupCustomPickerView() {
customPickerView = CustomPickerView.instantiateFromNib()
textField.inputView = customPickerView
customPickerView.datePickerView.addTarget(self, action: #selector(PickerVC.datePickerValueChanged(sender:)), for: UIControlEvents.valueChanged)
}

これでDatePickerを実現できます。


コードのみでUIDatePickerを生成

コード: https://github.com/fuwamaki/function_confirm/tree/master/FunctionConfirm/Picker/CodeOnlyPickerView

xibファイルなどは設けず、UIViewなどのクラスを作成して、


import UIKit

final class CodeOnlyPickerView: UIView {

var datePicker: UIDatePicker = UIDatePicker()

override init(frame: CGRect) {
let view = CGRect.init(x: 0, y: 0, width: 320, height: 216)
super.init(frame: view)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

func setupDatePicker() {
datePicker.datePickerMode = .date
datePicker.locale = Locale.current
datePicker.maximumDate = Date()
addSubview(datePicker)
}
}

用いたいViewから参照して利用します。


func setupDatePicker() {
let datePickerView = CodeOnlyPickerView()
textField.inputView = datePickerView.datePicker
datePickerView.datePicker.addTarget(self, action: #selector(PickerVC.datePickerValueChanged(sender:)), for: UIControlEvents.valueChanged)
}

別にUIViewクラスを特に設けず、 UIDatePicker をViewController側のクラスで生成して利用するっていうのでも全然OKだと思います。

ともあれ、これでDatePickerをコードのみで実現できます。


比較

最新の端末で比較したら、基本的に誤差レベルです。あまり差はありません。

そこで分かりやすいように、5年以上前の端末(iPhone5S)で動作比較します。

mp4からgifに変換したら全体的に遅くなってしまったんですけど許容してくださいm(__)m

比較すると、コードのみの方が少しだけ早いことが分かります。


まとめ

この記事を見てカスタムフォントを疑ったりしたのですが、違うようでした。

http://tech-tokyobay.manju.tokyo/archives/358

原因は明確じゃなくてアレな感じですが、この記事がどなたかの役に立てば幸いです。