UILongPressGestureRecognizer only checks for numberOfTouchesRequired at initial touch - ios

I have an app that has three long press gestures for 1,2, and 3 touches.
An Issue: through testing, my success rate of getting 2 or 3 touches to register correctly at the start of gesture recognition was far less than 100%. In further testing, it appears that the UILongPressGestureRecognizer [LPGR] only checks for the number of touches at the start and fails instantly if the number of touches is not what it's expecting.
My (potential) solution: I have started building a generic UIGestureRecognizer that will check for the number of touches at the end of a time interval, then pass touches to whatever branch of code that handles what was 1,2,and 3 touches.
My Question: Is there a better way? And barring that, is there a way to use the code already in an existing gestureRecognizers? I have not been able to actually change the state through reference (someRecognizer.state = .changed does not seem to do anything)

Related

Xcode UI test: How can I check something in the UI while a gesture is in progress?

My app supports a kind of dragging/panning gesture: The gesture begins after a short delay when the user presses the screen with one finger, and keeps pressing. The user can then drag/pan pan around the screen while keeping the finger on the screen. The gesture ends when the user lifts the finger.
While the user drags/pans around the screen the UI continuously updates. Among other things, a label is continously updated with a text that has certain information about the current gesture location. I would like to write a UI test that not only simulates the gesture, but also checks how the UI is updated while the gesture is in progress.
I have found the XCUICoordinate class which has the pressForDuration:thenDragToCoordinate: method. This looks as if it would allow me to simulate the gesture, but I can't see any way how I could, for instance, check that the label I mentioned contains a certain text while the gesture is in progress.
Is there an API that allows me to write the desired UI test?
My app is written in Objective-C, but a Swift answer is also acceptable.

Recognize long press in swift without UILongPressGestureRecognizer

I'm building an app around gesture recognition.
I've already built my code with recognition of taps, swipes (even with multiples fingers), pinches.
Now I'd like to recognize long press gesture without using UILongPressGestureRecognizer because it enters in conflit with my recognition of other gesture after (I tried).
What I'm currently doing is that I get the time in touchesBegan, in touchesMoved i calculate the time difference, and if it's greater than 400ms (for exemple), i call a function.
The thing is that this function is only called when the finger moved a bit and not when it's perfectly static.
Another option is to set a kind of delay in the touchesBegan and check if the finger is still on the screen after 400ms and then call the function.
How could I do that without blocking the rest of the gesture recognition ?
The aim of this long press would be to do a variation of intensity of a light or something like that (from 0 to 1s, light increase until max is reach, and then lower until minimum etc).
Next, I'll try to recognize a rotation gesture (with only one finger), so if you also have an answer for this, that'd be perfect.
Thanks !
Do not set delay. Start a timer that will fire after 400ms. In touchesEnded invalidate the timer, in case it was called before 400ms. When the timer fires, call the desired function.
As to your second question, probably you will need to calculate the trajectory of the points in touchesMoved method. If somehow the moves resemble rotation (you will need some kind of threshold for that), call the appropriate function.

Avoid triggering touchesBegan: until a swipe gesture recognizer fails

I'm making a game on the iPad where the player swipes up, down, left, or right to move the character. An attack is controlled by touchesBegan:withEvent:
My problem is that the character attacks whenever he moves.
Is there a way to set up a swipe gesture so the code doesn't run touchesBegan:withEvent: until it sees if the motion is the beginning of a swipe or not?
This is not too easy of a task. Without using some custom gestures I would suggest you to try the combination of UISwipeGestureRecognizer and UILongPressGestureRecognizer. I know this sound silly but it is not: An UILongPressGestureRecognizer acts pretty much the same as the pan gesture so even if the finger is dragged you will receive events. You need to set some proper minimum duration till it fires (depends on the swipe gesture) and some large minimum drag length so it doesn't get canceled for dragging. You need to remove the touch event methods then and move the code to long press gesture action.
To explain the result, your long press gesture will (if set correctly) work just the same as touch events except it will wait for specified duration. If in that duration a swipe is detected your long press gesture will not fire. Seems just what you need...

UIButton TouchUpInside sometimes not firing

I am creating UIButtons programmatically and set their targets as well. Most of the time TouchDown-TouchDragInside-TouchUpInside chain seems to work properly but if I perform this chain of events fast (about 2-3 times per second) method bound to TouchUpInside is sometimes not firing.
From my understanding UIEvents will always fire even if they don't fire immediately. Is this a known issue that I can't seem to find anything about? What can I do about it, besides touching things slower?
I think you create button can switch and click.if so ,the two gesture will also do not handle well, you can add swipe gesture on the button , the it work well;Hope can help you.

How do I implement multitouch on iOS

I'd like to implement multitouch, and I was hoping to get some sanity checks from the brilliant folks here. :)
From what I can tell, my strategy to detect and track multitouch is going to be to use the touchesBegan _Moved and _Ended methods and use the allTouches method of the event parameter to get visibility on all relevant touches at any particular time.
I was thinking I'd essentially use the previousLocationInView as a way of linking touches that come in with my new events with the currently active touches, i.e. if there is a touchBegan for one that is at x,y = 10,14, then I can use the previous location of a touch in the next message to know which one this new touch is tied to as a way of keeping track of one finger's continuous motion etc. Does this make sense? If it does make sense, is there a better way to do it? I cannot hold onto UITouch or UIEvent pointers as a way of identifying touches with previous touches, so I cannot go that route. All I can think to do is tie them together via their previouslocationInView value (and to know which are 'new' touches).
You might want to take a look at gesture recognizers. From Apple's docs,
You could implement the touch-event handling code to recognize and handle these gestures, but that code would be complex, possibly buggy, and take some time to write. Alternatively, you could simplify the interpretation and handling of common gestures by using one of the gesture recognizer classes introduced in iOS 3.2. To use a gesture recognizer, you instantiate it, attach it to the view receiving touches, configure it, and assign it an action selector and a target object. When the gesture recognizer recognizes its gesture, it sends an action message to the target, allowing the target to respond to the gesture.
See the article on Gesture Recognizers and specifically the section titled "Creating Custom Gesture Recognizers." You will need an Apple Developer Center account to access this.

Resources