DatePicker 在 iPhone 上位于 UINavigationBar 下,在 iPad 上运行良好
DatePicker goes under UINavigationBar on iPhone, works well on iPad
我有以下 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)
}
}
它在 iPad:
上运行良好
但是,在 iPhone 上,选择器向上滑动到 UINavigationBar
下方:
用于显示 DatePickerController
的代码完全相同,两种情况下的样式都是 UIModalPresentationStylePopover
。
更新:显示 DatePickerController 的代码:
@objc func presentDatePicker() {
let picker = DatePickerController()
let navC = UINavigationController(rootViewController: picker)
present(navC, animated: true, completion: nil)
}
已使用 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{[=10=].isActive = true}
}
我有以下 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)
}
}
它在 iPad:
上运行良好但是,在 iPhone 上,选择器向上滑动到 UINavigationBar
下方:
用于显示 DatePickerController
的代码完全相同,两种情况下的样式都是 UIModalPresentationStylePopover
。
更新:显示 DatePickerController 的代码:
@objc func presentDatePicker() {
let picker = DatePickerController()
let navC = UINavigationController(rootViewController: picker)
present(navC, animated: true, completion: nil)
}
已使用 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{[=10=].isActive = true}
}