iOS UIButton Touch Drag Enter not working as expected?
Asked Answered
T

4

5

I'm trying to create a button which will trigger an action when the user's touch is brought anywhere into the button (whether they touch down inside, or drag from outside to inside the button). Essentially, I need to create a way to trigger the action whenever a finger is inside of the button.

"Touch drag enter" combined with "touch down inside" sounds like it would do the job, but it seems to be working differently than what I need.

Also, I'd prefer if it can be done in storyboard rather than hard code (like touchesBegan/moved), but if there is no other way that's okay.

Tarshatarshish answered 15/5, 2013 at 3:23 Comment(0)
T
5

Touch drag enter will only gets called, when u start the touch inside the control and drag it outside the bounds of the control and then drag it back inside the control, without leaving the touch. So you need to subclass your button and achieve the required functionality.

Tybie answered 15/5, 2013 at 4:14 Comment(0)
D
3

Either you will have to bind all the events one by one with the method you are intending to invoke on button press from IB.

OR

You can try register your button for UIControlEventAllTouchEvents inside your code. Here is an example that might be helpful

[_btnRoundRect addTarget:self action:@selector(btnPressedAction) forControlEvents:UIControlEventAllTouchEvents];


- (void)btnPressedAction{
    NSLog(@"Bttn pressed");
}
Directly answered 15/5, 2013 at 3:58 Comment(0)
D
0

When setting the connection in IB Touch Down should be what you're looking for. Any time the user's finger hits the button the action will be called.

Dame answered 15/5, 2013 at 3:49 Comment(1)
This does not address OP's need for actions to be triggered when touch is brought into the button.Faxen
T
0

Just had this problem and although I see this question is old, I guess someone might find it as well...

My solution was to use touchesBegan, touchesMoved, touchesEnded and touchesCancelled.

I disabled my buttons although you can turn them into UIViews I guess... then in touchesBegan I use .point(inside:) on all touch events and check on all buttons, calling the buttonDown function on the ones that are touched.

Then on touchesMoved I check again but using both the current touch position and the previous one to see if the touch entered a new button. Basically if a button is touched by the old one and not the new one I call the buttonUp funcion for that button. If it's the other way around I call the buttonDown funcion

Last, on the touchesEnded and touchesCancelled I just see what button is being touched and call the buttonUp function.

I've tested it with multitouch on a real device and in Mac Catalyst and both seem to work fine. It was a quick solution that didn't make it necessary to change anything else from the regular "buttons with target/actions" solution I had before...

Example:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            for b in keys {
                if b.point(inside: touch.location(in: b),with:nil) {
                    keyDown(b)
                }
            }
        }
    }

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            for b in keys {
                if b.point(inside: touch.location(in: b),with:nil) && !b.point(inside: touch.previousLocation(in: b), with:nil) {
                    keyDown(b)
                } else if b.point(inside: touch.previousLocation(in: b), with:nil) && !b.point(inside: touch.location(in: b),with:nil) {
                    keyUp(b)
                }
                
            }
        }
    }
    
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            for b in keys {
                if b.point(inside: touch.location(in: b),with:nil) {
                    keyUp(b)
                }
            }
        }
    }
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            for b in keys {
                if b.point(inside: touch.location(in: b),with:nil) {
                    keyUp(b)
                }
            }
        }
    }
Tb answered 8/3, 2022 at 2:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.