I have a UIView subclass that overrides UIResponder's touchesMoved: message. I've noticed that when I swipe my finger very quickly across the UIView, my touchesMoved: message only gets called every so often and not constantly getting messaged.
Any ideas?
Thanks.
According to Apple Developer Technical Support this is by design.
Related
For the purposes of making app demos and presentations, I would like to draw circles corresponding to touches, just like in the iOS simulator, but on the device itself.
Ideally, this would be orthogonal to other code. Perhaps a UIView which draws the circles and forwards the events, but event forwarding seems to require the other views be aware:
http://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html#//apple_ref/doc/uid/TP40009541-CH3-SW17
Is there a clean way of doing this?
(I can't use the simulator for demos because my app uses gestures, MIDI, and OpenGL)
thanks!
There is a framework call fingertips which is available through cocoapods.
http://cocoapods.org/?q=on%3Aios%20fingertips
This will do what you are asking.
I don't think there's a clean way of doing this. However, this is what I would try:
Use method swizzling to hook up to all your views by swizzling the methods
- touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
for the UIView class. In addition, you may also need to swizzle some methods of UIGestureRecognizer subclasses, since they may prevent the methods listed above from being called. This way you can do your own thing (e.g. draw the touch points on the screen), and also let the views handle the touches as before.
I am able to understand that when user just touches the view, touches Began and Ended called. When user swipes their hand on a view, touches Moved method gets called. But when does touches Cancelled get called or by what action on user this method gets called?
I think probably the most common reason for touchesCancelled being called (since iOS 3.2 anyway) is following the recognition of a gesture by a UIGestureRecognizer. If your view has any kind of gesture recognizer attached to it then it is often very important to provide a custom implementation of the touchesCancelled method - note this includes ready made views that use gesture recognizers, including UIScrollView.
By default, gesture recognizers cancel the delivery of touches to the hit-test view upon recognition, although this behaviour can be disabled. This involves sending the touchesCancelled message to that view, most likely following a touchesBegan or touchesMoved message. If your touch handling code is relying on code implemented in the touchesEnded method, it is possible this may never be fired and some kind of serious problem could occur, hence the need to properly tie up any loose ends in touchesCancelled.
The ins and outs of gesture recognizer functionality is obviously a bit more complex than I've mentioned here - I would thoroughly recommend reading Apple's Gesture Recognizers documentation.
Also, check out the WWDC videos on gesture recognizers (starting from 2010).
Note: touches also get cancelled if you start a UIView animation after touchesBegan. To prevent this make sure you include UIViewAnimationOptionAllowUserInteraction:
e.g.
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.aView.hidden = NO;
self.aView.alpha = 1;
} completion:nil];
From the Apple Reference documents
Sent to the receiver when a system
event (such as a low-memory warning)
cancels a touch event.
Discussion
This method is invoked when the Cocoa
Touch framework receives a system
interruption requiring cancellation of
the touch event; for this, it
generates a UITouch object with a
phase of UITouchPhaseCancel. The
interruption is something that might
cause the application to be no longer
active or the view to be removed from
the window
When an object receives a
touchesCancelled:withEvent: message it
should clean up any state information
that was established in its
touchesBegan:withEvent:
implementation.
The default implementation of this
method does nothing. However immediate
UIKit subclasses of UIResponder,
particularly UIView, forward the
message up the responder chain.
And, from the Event Handling Guide for iOS, p. 19:
It sends the touchesCancelled:withEvent: message when the touch sequence is cancelled by a system event, such as an incoming phone call.
I was handling touchesBegan()/touchesMoved() on a view under UIScrollView, which is challenging. My touches kept cancelled by somewhere when I pinch (somehow it is OK with single touch movement), I was investigating how to stop being cancelled. I figured out, that there is a property Can Cancel On Scroll on UIScrollView, and you may check it off to stop being cancelled, if your case is similar to my case.
It sounds there are many cases where your touches are being cancelled, so my answer is just one of them.
Can i create custom touch events for iPhone?? will the device support for creating my own touch event handling ?
Take a look at the UIResponder class:
http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIResponder_Class/Reference/Reference.html
You will probably want to implement the touchesBegan:withEvent:, touchesEnded:withEvent: and touchesCancelled:withEvent: methods. These will all be called with an NSSet of UITouches that you can do whatever you want with.
As of the 3.2 SDK there are UIGestureRecognizer classess. They do not play well with the older UIResponder calls, but if you can do 3.2 only they are easier to get going.
There are a number of handy subclasses, such as UIRotationGestureRecognizer for handling rotation.
If you are extending Apple classes like UIScrollView you must use gesture recognizers with 3.2 and later because when a gesture recognizer cancels it will cancel your UIResponder call tracking as well. If you are handling all the gesture tracking this is not an issue.
Since the touch functions won't work until they are subclasses for the UIScrollView, I have subclassed them and get the touch coordinates in the subclass. But all my operations are being done in MainViewController. How can I send this value there? Might seem an easy question, but it is taking a lot of time for me.
I don't know what your answer is, but I just learned this technology a few days ago also. It was that, in the touchesBegan method of the view, I called
[self.nextResponder touchesBegan: touches withEvent: event];
and then wrote the touches began event in the view controller to which this passed the event.
Seems like no solution could be simpler.
John Doner
Without subclassing a UIResponder class(e.g. UIView) and overriding its touchesBegan:withEvent: method, is it possible to get informed of touch events of a UIResponder class?
This question was answered here.
Your question is somewhat confusing...'without subclassing UIResponder...can you get informed of touch events of UIResponder?' Are you asking if you can add touchesBegan/Moved/Ended/Cancelled events to any NSObject?!? I'm not comfortable enough with the framework yet to know for sure if those methods would be called if they were implemented as a category on or subclass of NSObject?!?
But, regardless of what you're doing, the top (end) of the responder chain is UIApplication (also a subclass of UIResponder) and if you have an iPhone app then you have a singleton of UIApplication which you can query for touch events...