はじめに
上記の記事ではPicker
でしたが、今回はDatePicker
です。
DatePicker
にもwheelスタイルが存在し、Picker
と同様に壊れています。
使い物になるDatePicker
をUIKitを使って作っていきます。
問題
struct ContentView: View {
@State var date: Date = Date()
var body: some View {
DatePicker("", selection: $date, displayedComponents: .hourAndMinute)
.datePickerStyle(WheelDatePickerStyle())
.frame(width: 200, height: 80, alignment: .center)
.background(Color.yellow)
.clipped()
}
}
このようになります。(わかりやすいように背景色を付けてます)
一見問題なさそうに見えますが重大なバグが潜んでいます。
下記の画像の青い部分が全てDatePicker
の判定になっています。
どういうことかと言うと、青い部分をスクロールすればホイールが反応してしまう訳です。
実装
WheelTimePickerView
struct WheelTimePickerView: UIViewRepresentable {
@Binding private var selection: Date
init(selection: Binding<Date>) {
self._selection = selection
}
func makeUIView(context: Context) -> UIDatePicker {
let picker = UIDatePicker(frame: .zero)
picker.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
picker.preferredDatePickerStyle = .wheels
picker.datePickerMode = .time
picker.addTarget(context.coordinator, action: #selector(Coordinator.changed(_:)), for: .valueChanged)
return picker
}
func updateUIView(_ uiDatePicker: UIDatePicker, context: Context) {
uiDatePicker.date = selection
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject {
var wheelTimePickerView: WheelTimePickerView
init(_ wheelTimePickerView: WheelTimePickerView) {
self.wheelTimePickerView = wheelTimePickerView
}
@objc func changed(_ sender: UIDatePicker) {
self.wheelTimePickerView.selection = sender.date
}
}
}
完成形
おわり
iOS16では修正されていることを願います