最近「この画面遷移なぜか遅い...なぜだ...」と思い、真面目に調査したところ、
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
原因は明確じゃなくてアレな感じですが、この記事がどなたかの役に立てば幸いです。