Search code examples
iosobjective-cuiviewuievent

Get the last touch event on UIView


Note: This is a question similar to what is asked here, but the answer provided there is not exactly a solution in my case. The question's objective is different too. Reference: touchesBegan - Only needs the last touch action - iPhone

I am trying to handle multiple touches in a UIView. I need to get the exact touch positions in order.

Currently, I am attaching a selector like this:

[myView addTarget:self action:@selector(touchBegan:withEvent:) forControlEvents: UIControlEventTouchDown];

This is my handler,

- (void)touchBegan:(UIButton *)c withEvent:ev {
    UITouch *touch = [[ev allTouches] anyObject];

The problem here is that [ev allTouches] returns an NSSet that is unordered, so I am unable to get the exact last location of the touch event in case of multiple touches.

Is there a way I can get the last location in the case when multiple touches are handled?


Solution

  • You can always create a subclass of your View and override hitTest to get the exact touch point

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        debugPrint(point)
        return super.hitTest(point, with: event)
    }
    

    Here am just logging touch point. Just to show how it works with I have added touchesBegan in my ViewController and logged first touch point from touches set

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        debugPrint(touches.first)
    }
    

    Here is the console log for both

    (175.66667175293, 175.33332824707)

    Optional( phase: Began tap count: 1 force: 0.000 window: ; layer = > view: > location in window: {175.66665649414062, 175.33332824707031} previous location in window: {175.66665649414062, 175.33332824707031} location in view: {175.66665649414062, 175.33332824707031} previous location in view: {175.66665649414062, 175.33332824707031})

    So hit test says, your touch point is (175.66667175293, 175.33332824707) while touches.first says location in view : {175.66665649414062, 175.33332824707031} which are basically same.

    Can hitTest be used as replacement to touchBegan? No.

    Thats why I had asked in comments above what exactly are you trying to achieve. If you are looking for continuous monitoring of touches than touchBegan, touchMove, touchEnd are the delegates you should opt for, but if you are trying to monitor a single touch and find its exact touch point you can always make use of hitTest

    Hope it helps