Sira Lam
Sira Lam

Reputation: 5367

UIView touchesBegan not being called

I have created a subclass of UIView and added in Views by referencing an xib file.

I overrided the touchesBegan and touchesEnd functions in order to have customized effect of "color changes when user presses on this view".

Below is this subclass:

class CustomUIView: UIView {

    @IBOutlet var contentView: UIView!

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

    required init? (coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit () {
        Bundle.main.loadNibNamed("CustomUIView", owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touch begin")
        super.touchesBegan(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touch ended")
        super.touchesEnded(touches, with: event)
    }

}

However, touchesBegan and touchesEnd are never called.

I googled and stackoverflowed, tried for 3 hours already, but cannot find any working solution to this simple question....

Below are what I have tried:

  1. Made sure all superviews have UserInteraction enabled. I even captured View Hierarchy to check this.
  2. Added an IBAction of touchUpInside to see whether this IBAction can be triggered. The answer is yes.
  3. Subclass UIControl instead and override beginTracking instead. But it is also not triggered.

Below are the properties I can see from ViewHierarchy of this CustomView:

  1. It is enabled
  2. User Interaction Enabled On
  3. Multiple Touch Off
  4. Alpha 1
  5. Background <nil color> (I have also tried to set it to have a color. Not working.)
  6. Opaque On
  7. Hidden Off
  8. Clears Graphics Context On
  9. Clip to Bounds Off
  10. Autoresize Subviews On

Help very much appreciated!

Upvotes: 3

Views: 7527

Answers (2)

Sira Lam
Sira Lam

Reputation: 5367

Thanks to @Fahri Azimov 's comment, the reason is contentView has User Interaction Enabled On. Therefore it consumed all touch events before passing to CustomUIView. I have upvoted his comment.

The lesson is, the rootView of the xib file is not CustomUIView itself but one of its child.

Upvotes: 3

karthikeyan
karthikeyan

Reputation: 3888

Kindly try this, its due to frame of your CustomView

class CustomUIView: UIView {

    var contentView: UIView!
    override init (frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init? (coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    func loadFromNib() -> UIView {
                let bundle = Bundle(for: type(of: self))
                let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
                let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
                return view
        }
    private func commonInit () {
        contentView = self.loadFromNib()
        addSubview(contentView)
        contentView.frame = self.bounds
        self .isUserInteractionEnabled = true
        contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touch begin")
        super.touchesBegan(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touch ended")
        super.touchesEnded(touches, with: event)
    }

}

I can see a logs in console

enter image description here

Drag one UIView in your ViewController and set your customview class as CustomUIView

enter image description here

Upvotes: 0

Related Questions