Search code examples
iosswiftuilabeluipickerviewuitapgesturerecognizer

Trigger PickerView from UILabel to have it Modally Appear From the Bottom the Screen and not Hide/Unhide It


I have label with a gesture recognizer inside a collectionView cell. When the user touches the label I want a pickerView to appear similar to how it would appear when a pickerView is attached to a textField.

I tried myLabel.inputView = pickerView

I got this error below.

Cannot assign to property: 'inputView' is a get-only property

I came across some threads where people were hiding and unhiding the pickerView instead of it popping up and lowering like a it does from a textField but no one explained why they hid/unhid it.

How can I trigger a PickerView from a UILabel?

It should be noted that I don't want to hide/unhide it like the other answers that I read.

class MyCell: UICollectionViewCell {

    lazy var pickerView = UIPickerView()

    let myLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.isUserInteractionEnabled = true
        return label
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(triggerPickerView))
        myLabel.addGestureRecognizer(tapGesture)

    }

    @objc func triggerPickerView() {
       print("triggerPickerView")
    }
}

Solution

  • I found the answer.

    In the comments @AshlyMills said the reason I can't trigger the picker view from a UILabel is because: "It's not possible because inputView is a get only property on UIResponder"

    My workaround was to a use a UITextField and just make it clear. I added the pickerView as an inputView to the textFiled. I laid it directly over the label and by pressing it the pickerView appears modally from the bottom and the label is still visible. I removed the gesture recognizer because it wasn't necessary.

    class MyCell: UICollectionViewCell {
    
        lazy var pickerView = UIPickerView()
    
        let myLabel: UILabel = {
            let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false
            label.isUserInteractionEnabled = true
            return label
        }()
    
        let clearTextField: UITextField = {
            let textField = UITextField()
            textField.translatesAutoresizingMaskIntoConstraints = false
            textField.backgroundColor = .clear
            return textField
         }()
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
    
            addSubview(clearTextField)
    
            clearTextField.topAnchor.constraint(equalTo: myLabel.topAnchor).isActive = true
            clearTextField.leftAnchor.constraint(equalTo: myLabel.leftAnchor).isActive = true
            clearTextField.rightAnchor.constraint(equalTo: myLabel.rightAnchor).isActive = true
            clearTextField.bottomAnchor.constraint(equalTo: myLabel.bottomAnchor).isActive = true
    
            clearTextField.inputView = pickerView
        }
    }