I have the following code for the DatePickerController:
import UIKit
@objc protocol DatePickerControllerDelegate: AnyObject {
func datePicker(controller: DatePickerController, didSelect date: Date)
func datepickerDidDismiss(controller: DatePickerController)
}
final class DatePickerController: UIViewController {
@objc weak var delegate: DatePickerControllerDelegate?
@objc public var date: Date {
get {
return datePicker.date
}
set(value) {
datePicker.setDate(value, animated: false)
}
}
@objc public lazy var datePicker: UIDatePicker = {
let v = UIDatePicker()
v.datePickerMode = .date
return v
}()
override var preferredContentSize: CGSize {
get {
return datePicker.frame.size
}
set(newValue) {
super.preferredContentSize = newValue
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(datePicker)
datePicker.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleBottomMargin]
view.backgroundColor = .white
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done,
target: self,
action: #selector(DatePickerController.doneButtonDidTap))
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(DatePickerController.cancelButtonDidTap))
}
@objc private func doneButtonDidTap() {
delegate?.datePicker(controller: self, didSelect: date)
}
@objc private func cancelButtonDidTap() {
dismiss(animated: true, completion: nil)
delegate?.datepickerDidDismiss(controller: self)
}
}
It works well on iPad:
However, on iPhone the picker slides up under the UINavigationBar
:
The code used to show the DatePickerController
is absolutely the same, the style is UIModalPresentationStylePopover
in both cases.
Update: code to present DatePickerController:
@objc func presentDatePicker() {
let picker = DatePickerController()
let navC = UINavigationController(rootViewController: picker)
present(navC, animated: true, completion: nil)
}
Fixed using AutoLayout:
private func configureLayout() {
datePicker.translatesAutoresizingMaskIntoConstraints = false
[datePicker.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
datePicker.leadingAnchor.constraint(equalTo: view.leadingAnchor),
datePicker.trailingAnchor.constraint(equalTo: view.trailingAnchor),]
.forEach{$0.isActive = true}
}