【问题标题】:DatePicker not closing after tap outsideDatePicker 在外面点击后没有关闭
【发布时间】:2016-12-07 00:45:24
【问题描述】:

在我的应用程序中,我有一个文本字段来添加出生日期。一旦用户点击文本字段,我就会在弹出窗口中添加一个 datePicker。 datePicker 正确显示,并且在用户选择它在文本字段中显示的日期后。问题是在选择 datePicker 未关闭的日期之后。

这是我的代码:

class BController: UIViewController, UITextFieldDelegate {

 @IBOutlet weak var dateOfBirth: UITextField!

    let datePicker = UIDatePicker()




    func textFieldShouldReturn(textField: UITextField) -> Bool {
         textField.resignFirstResponder()
       // self.view.endEditing(true)
        return true
    }



    func textFieldDidBeginEditing(textField: UITextField){
         if textField == dateOfBirth{
           // let datePicker = UIDatePicker()

            datePicker.datePickerMode = UIDatePickerMode.Date

            datePicker.backgroundColor = UIColor.blackColor()
            datePicker.setValue(UIColor.whiteColor(), forKey: "textColor")

            textField.inputView = datePicker
            datePicker.addTarget(self, action: "datePickerChanged:", forControlEvents: .ValueChanged)
        }
    }

    func datePickerChanged(sender: UIDatePicker){

        let formatter = NSDateFormatter()
        formatter.dateFormat = "dd-MM-yyyy"
        //    formatter.dateStyle = .ShortStyle
        //  formatter.timeStyle = .NoStyle
        dateOfBirth.text = formatter.stringFromDate(sender.date)

    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        print("touch happened")
        self.view.endEditing(true)

    }


    override func viewDidLoad() {
        super.viewDidLoad()
        dateOfBirth.delegate = self
        text1.delegate =  self
        text2.delegate = self

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



}

我得到控制台输出:

无法识别的选择器发送到实例 0x7 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[BController getCalendar:]:无法识别的选择器发送到实例 0x78789050”

如何解决这个问题?我正在使用 Xcode 6.2。如果您需要更多信息,请告诉我。

【问题讨论】:

  • 请在您的 getCalendar 函数中向我们展示代码
  • @Asike 我没有名为 getCalendar 的方法。我是 iSO 开发的新手,我遵循了这个过程的教程。我在那里也看不到任何名为 getCalendar 的方法。我不知道这个错误引用来自哪里。

标签: ios swift datepicker


【解决方案1】:

正如文档所说:

var inputView: UIView? 当文本字段成为第一响应者时显示的自定义输入视图。

所以你应该先初始化你的 datePicker,然后在 viewDidLoad 方法中将它赋值给 dateOfBirth 的 inputView 属性,而不是 textFieldDidBeginEditing 方法。

要在外部点击关闭 datePicker,请使用在 self.view 上添加的 UITapGestureRecognizer

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let datePicker = UIDatePicker.init()
        textField.inputView = datePicker

        let gestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(backgroundTap(gesture:)));
        view.addGestureRecognizer(gestureRecognizer)

    }

    func backgroundTap(gesture : UITapGestureRecognizer) {
        textField.resignFirstResponder() // or view.endEditing(true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

你的错误是当调用textFieldDidBeginEditing方法时,UITextField对UIDatePicker一无所知。

【讨论】:

  • 谢谢。我试过了,但结果还是一样,我得到了同样的例外。有什么想法吗?
【解决方案2】:

我知道这是一个老问题,显示日期选择器的方法略有不同,但我认为这个想法仍然可以应用。

尝试将 Date Picker View 包装在 UIView() 容器中,该容器包含手势检测器并跨越整个屏幕。

class ViewController: UIViewController {

var toolBar = UIToolbar()
var datePicker  = UIDatePicker()
var datePickerContainer = UIView()

override func viewDidLoad() {
    super.viewDidLoad()
}

@IBAction func showDatePicker(_ sender: UIButton) {
    datePicker = UIDatePicker()
    datePicker.autoresizingMask = .flexibleWidth
    datePicker.datePickerMode = .dateAndTime
    datePicker.preferredDatePickerStyle = .wheels
    datePicker.backgroundColor = .clear
    
    datePicker.addTarget(self, action: #selector(self.dateChanged(_:)), for: .valueChanged)
    datePicker.frame = CGRect(x: 0.0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 300)
    
    datePickerContainer = UIView()
    datePickerContainer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
    datePickerContainer.backgroundColor = .clear
    datePickerContainer.addSubview(datePicker)
    self.view.addSubview(datePickerContainer)
    
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(touchedOutsideOverlay(_:)))
    datePickerContainer.addGestureRecognizer(tapGesture)
    
    toolBar = UIToolbar(frame: CGRect(x: 0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 50))
    toolBar.barStyle = .black
    toolBar.items = [
        UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
        UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.onDoneButtonClick))
    ]
    toolBar.sizeToFit()
    self.view.addSubview(toolBar)
}

@objc func dateChanged(_ sender: UIDatePicker?) {
    let dateFormatter = DateFormatter()
    
    if let date = sender?.date {
        print("Picked the date: \(dateFormatter.string(from: date))")
    }
}

@objc func touchedOutsideOverlay(_ sender: UITapGestureRecognizer){
    removeDatePicker()
}

@objc func onDoneButtonClick() {
    removeDatePicker()
}

func removeDatePicker(){
    toolBar.removeFromSuperview()
    datePicker.removeFromSuperview()
    datePickerContainer.removeFromSuperview()
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多