UIImageView isUserInteractionEnabled = true doesn't work

2.1k Views Asked by At

The following DateField class has a date field and an icon on it. For some reason fieldIcon.isUserInteractionEnabled = true has zero affect and doesn't pass user tap to the field. Am I missing something?

import UIKit
import SnapKit

protocol DateFieldDelegate: class {
    func dateSelected(_ dateField: DateField, date: Date)
}

class DateField: UIView, UITextFieldDelegate {

    weak var delegate: DateFieldDelegate?
    let field = UITextField()
    private var datePicker: UIDatePicker?

    convenience init(withStartDate startDate: Date) {
        self.init()

        datePicker = prepareDatePicker()
        guard let datePicker = datePicker else { return }
        field.inputView = datePicker
        field.delegate = self

        addSubview(field)
        field.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.leading.equalToSuperview()
            make.trailing.equalToSuperview()
            make.height.equalTo(37)
            make.bottom.equalToSuperview()
        }

        let fieldIcon = UIImageView(image: UIImage(asset: Asset.calendar))
        field.addSubview(fieldIcon)
        fieldIcon.isUserInteractionEnabled = true  // doesn't work
        fieldIcon.snp.makeConstraints { make in
            make.width.equalTo(21)
            make.height.equalTo(23)
            make.trailing.equalToSuperview().offset(-10)
            make.centerY.equalToSuperview()
        }

        setStyle(.regular)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        guard let date = datePicker?.date else { return }
        field.text = date.formatToString()
        delegate?.dateSelected(self, date: date)
    }

    private func prepareDatePicker() -> UIDatePicker {
        let datePicker = UIDatePicker()
        datePicker.datePickerMode = .date
        datePicker.setDate(Date(), animated: false)
        datePicker.locale = Language.appLocale()
        return datePicker
    }
}
1

There are 1 best solutions below

3
On

Not sure if I've missed something in your code but you need to add some kind of action to the image, enabling userInteractionEnabled does not tell it to recognise taps on the item and what to do when this happens. You need to add a UITapGestureRecogniser to the UIImageView

let fieldIcon = UIImageView(image: UIImage(asset: Asset.calendar))
field.addSubview(fieldIcon)
fieldIcon.isUserInteractionEnabled = true  // doesn't work

let fieldIcon = UIImageView(image: UIImage(asset: Asset.calendar))
field.addSubview(fieldIcon)

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(calenderIconTapped))
fieldIcon.addGestureRecognisor(tapGesture)

func calenderIconTapped() {
    // show the picker
}

UPDATE:

After re-reading your question, I understand what your attempting to do now. If you want any taps on the image view to passthrough to the UITextField underneath you need to do the opposite of what you tried... you need to set userInteractionEnabled to false on the UIImageView

fieldIcon.isUserInteractionEnabled = false