I am using UIDatePicker
to pick a date from the user. In devices below IOS 16, it works fine, but in IOS 16+ devices, the calendar cuts from the bottom. Below is my code,
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePicker.Mode.date
if #available(iOS 14, *) {
datePickerView.preferredDatePickerStyle = .inline
}
sender.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(MyViewController.datePickerValueChangedNew(sender:)), for:
UIControl.Event.valueChanged)
Issue:
This might be a bug in iOS 16. When the input view is presented, I see this message in the log:
[UICalendarView] UICalendarView's height is smaller than it can render its content in; defaulting to the minimum height.
My guess is that when presenting the input view, there is a one moment where a very small height for the date picker is required, "smaller than it can render its content". This causes the date picker to change its frame to use a default height. When the input view is fully presented, the date picker doesn't re-layout to account for the safe area for some reason.
You can simply work around this by nesting the date picker in a UIView
. Constrain the date picker to the UIView
's safe areas:
// here I've used 700 as the height
// feel free to choose another number
let container = UIView(frame: .init(x: 0, y: 0, width: 0, height: 700))
container.addSubview(datePickerView)
datePickerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
datePickerView.bottomAnchor.constraint(equalTo: container.safeAreaLayoutGuide.bottomAnchor),
datePickerView.topAnchor.constraint(equalTo: container.safeAreaLayoutGuide.topAnchor),
datePickerView.leadingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.leadingAnchor),
datePickerView.trailingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.trailingAnchor),
])
textfield.inputView = datePickerView
Running this on the iPad 12.9 inch simulator, I got:
Adjust the constraints appropriately if you want more space on the buttom.