ios - 在 iPhone X(及更高版本)上启动与键盘大小相同的 UIDatePicker

标签 ios swift xcode

我正在尝试构造一个 UIDatePicker,其高度与通过 keyboardDiDShow 通知观察到的用户键盘的高度相同。

键盘显示后,使用NotificationCenter Observer观察keyboardHeight。 UIDatePicker 在自定义 TableViewCell awakeFromNib() 函数中初始化。问题在于,只有在键盘确实显示调用 awakeFromNib() 之后发生的情况后,才能观察到 KeyboardHeight。有没有办法在初始化后更新 UIDatePicker 高度?

TableViewController

观察者:

`NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardDidShowNotification , object: nil)`

键盘高度:

@objc func keyboardWillShow(notification: Notification) -> CGFloat {
NSLog("Keyboard appeared")
if let keyboardSize = (notification.userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let heigth = keyboardSize.height
        keyboardHeight = heigth
        print(keyboardHeight)
        return heigth
    }
    return 0

TableViewCell

UIDatePicker 初始化:

let picker = UIDatePicker()
let tableView = ItemsTableViewController()

override func awakeFromNib() {
    // Initialization
    super.awakeFromNib()
    // UIDatePicker features
    picker.minimumDate = Calendar.current.date(byAdding: DateComponents(), to: Date())
    picker.datePickerMode = .date
    picker.addTarget(self, action: #selector(pickerValueToText(_:)), for: .valueChanged)

    // Size
    let screenWidth = UIScreen.main.bounds.width
    let size = CGSize(width: screenWidth, height: tableView.keyboardHeight)
    let frame = CGRect(origin: CGPoint(x: 0, y: 0), size: size)
    picker.frame = frame

    // Add toolbar to picker
    let toolbar = UIToolbar()
    toolbar.sizeToFit()
    let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let doneButton = UIBarButtonItem(title: "Next", style: .done, target: self, action: #selector(doneClicked))

    toolbar.setItems([flexibleSpace, doneButton], animated: true)
    dateTextField.inputAccessoryView = toolbar

结果是 UIDatePicker 创建时高度为 0,因为创建选择器时键盘尚未显示。

最佳答案

为了直接回答您的问题,有一种方法可以更新选择器的高度。您只需要能够从 keyboardWillShow 实现中引用选择器即可:

cell.picker.frame.height=keyboardSize.height

<小时/>

编辑:

刚刚意识到您可能正在界面构建器(xib 或 Storyboard)中编写单元格,这意味着您已经在使用自动布局。仅仅设置选择器的高度在这里并不能解决问题。您必须在界面构建器中为选择器的高度添加 NSLayoutConstraint,并设置其 constant 属性以在键盘出现后匹配键盘的高度。像这样的东西:

cell.datePickerHeightConstraint.constant = KeyboardSize.height

我仍然认为您应该考虑使用下面提到的解决方案。

<小时/>

但是,在我看来,您并没有采用最简单的方法。最简单的方法是将选择器设置为 dateTextFieldinputView。这样,选择器就会而不是显示键盘。将您的 awakeFromNib 实现更改为:

override func awakeFromNib() {

// Initialization
super.awakeFromNib()
// UIDatePicker features
picker.minimumDate = Calendar.current.date(byAdding: DateComponents(), to: Date())
picker.datePickerMode = .date
picker.addTarget(self, action: #selector(pickerValueToText(_:)), for: .valueChanged)

// Add toolbar to picker
let toolbar = UIToolbar()
toolbar.sizeToFit()
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: "Next", style: .done, target: self, action: #selector(doneClicked))

toolbar.setItems([flexibleSpace, doneButton], animated: true)
dateTextField.inputAccessoryView = toolbar
dateTextField.inputView = picker

此外,如果您有兴趣以现代方式编写 UI 代码,您应该使用自动布局而不是直接设置 UIView 的框架:https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html

<小时/>

编辑2:

UIInputView 子类中嵌入 UIDatePicker 可以匹配键盘高度:

class DatePickerInputView: UIInputView {
    let datePicker = UIDatePicker()

    var height: CGFloat = 320 {
        didSet {
            heightConstraint?.constant = height
        }
    }
    private var heightConstraint: NSLayoutConstraint?

    override var inputViewStyle: UIInputView.Style {
        get { return .default }
    }

    override var allowsSelfSizing: Bool {
        get { return true }
        set {}
    }

    init() {
        super.init(frame: .zero, inputViewStyle: .default)
        addSubview(datePicker)

        translatesAutoresizingMaskIntoConstraints = false
        datePicker.translatesAutoresizingMaskIntoConstraints = false
        let heightConstraint = datePicker.heightAnchor.constraint(equalToConstant: height)

        NSLayoutConstraint.activate([
            datePicker.topAnchor.constraint(equalTo: topAnchor),
            datePicker.bottomAnchor.constraint(equalTo: bottomAnchor),
            datePicker.leadingAnchor.constraint(equalTo: leadingAnchor),
            datePicker.trailingAnchor.constraint(equalTo: trailingAnchor),
            heightConstraint
            ])
        self.heightConstraint = heightConstraint
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

然后更改 keyboardWillShow 中的高度:

datePicker.height = keyboardSize.height

这是采用这种方法的存储库:https://github.com/AleksanderMaj/DatePickerInputView

关于ios - 在 iPhone X(及更高版本)上启动与键盘大小相同的 UIDatePicker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53997195/

相关文章:

ios - cgColor 和 UIColor 的区别

swift - 在 swift ( OS X ) 中从十六进制字符串获取 CGColor

ios - 演示前取消通知

iphone - iPhone 中的内置图像是否有记录?是否有它们的名称列表?

ios - 将钥匙串(keychain)共享添加到已有用户的生产应用程序

ios - 如何在 WatchOS 6 中将 Crown 输入打印到控制台

ios - 滚动并按搜索栏上的取消时应用程序崩溃

iphone - 适用于残疾人的iPad/iPhone应用程序

ios - 当 imageview 在里面时,Swift CollectionView 会改变大小

ios - Cocoa Touch Framework 架构问题/生产构建