日期选择器之外的键盘

Posted

技术标签:

【中文标题】日期选择器之外的键盘【英文标题】:Keyboard beyond date picker 【发布时间】:2017-05-27 14:10:05 【问题描述】:

我正在尝试在您点击文本字段时显示日期选择器。这一切似乎都工作正常,但一旦我关闭日期选择器,它就会显示键盘。

所以我基本上必须关闭它 2 次才能真正消失。

我为选择器创建了一个文本字段类,如下所示

EDIT 将所有代码移入 TEXTFIELD 类

protocol TextFieldPickerDelegate 
    func pickerValueDidChange(date: Date, pickerMode: UIDatePickerMode, sender: TextFieldPicker)


public class TextFieldPicker: UITextField, UITextFieldDelegate 

    var pickerMode: UIDatePickerMode = .date

    @IBInspectable var pickerType: String? 
        willSet 
            for s in (newValue?.lowercased().getStrings())! 
                switch s 
                case "date":
                    pickerMode = .date
                case "dateandtime":
                    pickerMode = .dateAndTime
                case "countdowntimer":
                    pickerMode = .countDownTimer
                case "time":
                    pickerMode = .time
                default:
                    pickerMode = .date
                
            
        
        didSet 
            setupTextField()
        
    

    var textFieldPickerDelegate: TextFieldPickerDelegate?

    func setupTextField() 
        createPicker()
    

    override public func draw(_ rect: CGRect) 
        super.draw(rect)

        delegate = self
    

    override public func caretRect(for position: UITextPosition) -> CGRect 
        return CGRect.zero
    

    override public func shouldChangeText(in range: UITextRange, replacementText text: String) -> Bool 
        return false
    

    public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
        return false
    

    public func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        self.resignFirstResponder()
        return true
    

    public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool 
        self.resignFirstResponder()
        return true
    

    func createPicker() 
        let datePicker = UIDatePicker()
        datePicker.datePickerMode = pickerMode
        datePicker.addTarget(self, action: #selector(pickerValueChange(_:)), for: .valueChanged)

        let pickerToolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
        pickerToolBar.tintColor = UIColor.gray
        let doneButton = UIBarButtonItem(title: NSLocalizedString("done", comment: ""), style: .done, target: self, action: #selector(closePicker(_:)))
        let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        pickerToolBar.setItems([space, doneButton], animated: true)

        self.inputView = datePicker
        self.inputAccessoryView = pickerToolBar
    

    func closePicker(_ sender: Any) 
        self.resignFirstResponder()
    

    func pickerValueChange(_ sender: UIDatePicker) 
        self.textFieldPickerDelegate?.pickerValueDidChange(date: sender.date, pickerMode: sender.datePickerMode, sender: self)
    

    public func getDateString(date: Date, format: String) -> String 
        let timeFormatter = DateFormatter()
        timeFormatter.dateFormat = format
        return timeFormatter.string(from: date)
    







// =================================================== OptionSet =================================================== \\
public struct PickerModes: OptionSet 
    private enum PickerMode: Int, CustomStringConvertible 
        case Date=1
        case DateAndTime=2
        case CountDownTimer=4
        case Time=8

        public var description: String 
            var shift = 0
            while (rawValue.hashValue >> shift != 1)  shift += 1 
            return ["date", "dateandtime", "countdowntimer", "time"][shift]
        
    
    public let rawValue: Int
    public init(rawValue: Int)  self.rawValue = rawValue 
    private init(_ mode: PickerMode)  self.rawValue = mode.rawValue 

    static let Date = PickerModes(PickerMode.Date)
    static let DateAndTime = PickerModes(PickerMode.DateAndTime)
    static let CountDownTimer = PickerModes(PickerMode.CountDownTimer)
    static let Time = PickerModes(PickerMode.Time)


extension String 
    func getStrings() -> [String] 
        var stringArray: [String] = []
        let strings = self.characters.split$0 == ",".map(String.init)
        for s in strings 
            let string = s.removeSpaces()
            stringArray.append(string)
        
        return stringArray
    

    func removeSpaces() -> String 
        if self.characters.first == " " 
            var copy = self
            copy.characters.removeFirst()
            return copy.removeSpaces()
         else 
            return self
        
    

这个类完全负责显示日期选择器并处理显示正确类型的日期选择器,以防一个屏幕中需要多个不同的选择器。

编辑 2 如果其他人尝试我的代码,它将正常工作而不会出现任何问题。我遇到的问题是我不小心将我的自定义类设置为包含我的UITextFieldUIView,所以当我点击文本字段时,它会首先触发UIView 的键盘,然后触发UIDatePicker 所以当UIDatePicker 辞职了,键盘还在。

【问题讨论】:

【参考方案1】:

我一直在做一些研究,在我看来,在文本字段中创建日期选择器的方法要简单得多。你可以只使用其中之一。 https://blog.apoorvmote.com/change-textfield-input-to-datepicker/

【讨论】:

你是同时添加还是单独尝试 @NoSixties 发生了什么 先是单独,然后在两者上,但没有为它做任何事情 @NoSixties 是在调用日期选择器时调用的创建日期选择器方法,如果不是何时调用 视图加载时调用创建日期选择器

以上是关于日期选择器之外的键盘的主要内容,如果未能解决你的问题,请参考以下文章

使用材料 ui 键盘日期选择器动态设置日期

Android,有啥方法可以禁用使用键盘在日期选择器内写入?

iPhone日期选择器而不是键盘?

点击日期字段时如何调出日期选择器?

引导日期选择器方向/放置

在移动设备上禁用 Bootstrap 日期选择器的键盘弹出窗口(Rails 4,Jquery)