Yianni_Zav
Yianni_Zav

Reputation: 51

UIDatePicker not fully popping up on UITextField click

The app I'm coding is an event-based app. On the screen where you would create a new event I have a UITextField with a UIDatePicker set as its input view initialized as:

lazy var eventDateTxt: UITextField = {
        let tf = UITextField()
        tf.attributedPlaceholder = NSAttributedString(string: "Pick Your Event Date",
                                     attributes: [NSAttributedString.Key.foregroundColor: UIColor.zipVeryLightGray])
        tf.font = .zipBody
        tf.borderStyle = .roundedRect
        
        tf.tintColor = .white
        tf.backgroundColor = .zipGray
        tf.textColor = .white
        tf.adjustsFontSizeToFitWidth = true
        tf.minimumFontSize = 10.0;
        
        let datePicker = UIDatePicker()
        datePicker.datePickerMode = .dateAndTime
        datePicker.minimumDate = Date()
        tf.inputView = datePicker
        
        datePicker.addTarget(self, action: #selector(dateChanged), for: .valueChanged)
        return tf
}()

dateChanged looks like this

@objc func dateChanged(sender: UIDatePicker){
        let dateFormat = DateFormatter()
        dateFormat.dateStyle = .long
        dateFormat.timeStyle = .short
        eventDateTxt.text = dateFormat.string(from: sender.date)
        
        event.startTime = sender.date
}

and although it doesn't matter, here is my code for the UITextFieldDelegate

extension NewEventViewController: UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        if textField == titleText {
            if textField.text == "Event Title" {
                textField.text = ""
            }
        }
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        if textField == titleText {
            if textField.text == "" {
                textField.text = "Event Title"
            }
        }
    }
}

Now the problem: When I click the UITextField to open the DatePicker, it pops up as a small pop up view on the bottom of the screen and looks like this:

https://ibb.co/WBJ9GsN

note the very bottom of the image.

Now if you click the date at the bottom there it opens the DatePicker as expected and looks like this:

https://ibb.co/N7VvfX6

when doing so an error comes up in the consol

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600002d79ea0 'UIView-bottom-readableContentGuide-constraint' UILayoutGuide:0x60000379d340'UIViewLayoutMarginsGuide'.bottom == UILayoutGuide:0x60000379d260'UIViewReadableContentGuide'.bottom   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-08-11 12:52:37.262846-0400 zip_official[93261:10730049] [DatePicker] UIDatePicker 0x7faa2732fe80 is being laid out below its minimum width of 280. This may not look like expected, especially with larger than normal font sizes.

Using the suggested breakpoint didn't lead me anywhere.

So my question: How do I make it so the DatePicker pops up immediately without the little bottom tab.

Upvotes: 1

Views: 1236

Answers (2)

iadcialim24
iadcialim24

Reputation: 4035

For better UI output

if #available(iOS 14.0, *) {
    datePicker.preferredDatePickerStyle = .inline
}  else if #available(iOS 13.4, *) {
    datePicker.preferredDatePickerStyle = .wheels
}

Upvotes: 0

Joke coder
Joke coder

Reputation: 273

This date picker thing is a lot of pain in the back. It changed twice for last two iOS versions. I had the same issue earlier and what I did was:

Make the date picker stick to the bottom (with some constant to place it a little above safe area). In your case, I would give it a frame.

let datePicker = UIDatePicker(frame: CGRect(x: eventDateTxt.frame.minX, y: eventDateTxt.frame.minY, width: view.frame.width, height: 150))

Some pseudo code (for iOS 14 and higher I guess):

let datePicker = UIDatePicker()
datePicker.preferredDatePickerStyle = .wheels

If your iOS version < 14, then maybe do it with frames.

Upvotes: 3

Related Questions