how to touch on animated object iOS - ios

For animation my UIImageView object I use these approaches:
Block animation
Begin/Commit method for animation UIView based object
The problem is next: When I try to tap on some object on my view it does not response to my action. Being animatable the object don't receive any calls from the main thread.
In my UIViewController I have method below that should handle touched object. All objects receive touch events but the objects which are using in animation block don't receive any events.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
Anybody knows what is the probem here?

In order for an animated view to recieve user events, UIViewAnimationOptionAllowUserInteraction must be passed into the options parameter.

Related

How to response a touch event which begin to touch down outside of a view and drag enter it in iOS

I want to response this kind of touch event on a view:begin to touch down outside of the view and drag enter it. I have tried to use the iOS UIControlEvent such as UIControlEventTouchDragEnter,UIControlEventTouchDragInside and the UIGesture, and I found no way can do this directly.
Finally, I implement it with my own way:Create a custom subclass of UIView and overwrite the method (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event and forward touch event up to the responder chain. In the touchesBegan, touchesMoved, touchesEnded method of parent view, I use the location of UITouch object to judge touch down outside of the view and drag enter it.
I am not satisfied with this way. Is there anyone can tell me a more efficient and elegant way to work out it? Thank you very much for your time and consideration.
begin to touch down outside of the view and drag enter it
You can never do this more "elegantly" because if your initial touch down is outside the view, then it is not associated with this view and never will be. Whatever view the touch's initial hit test associates it with, that is the view that will always be this touch's view throughout the gesture, and touch events will be sent only to that view. The default definition of hit testing is that the view that the initial touch is inside is the hit-test view, and that, by hypothesis, is not your view.

Detecting a second touch while holding a first touch in Cocos2d v3 iOS

I'm wanting to be able to detect the following in Cocos2d v3:
A touch is initiated and held, then a second touch occurs somewhere else on the screen. Think of holding with one finger, and tapping with a second.
I've tried to use - (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event but this is only called the first time the second touch occurs, not subsequently.
To be clear, if I hold a touch on the screen and then tap somewhere else, the above method is called. But if I continue holding the first touch and then tap a second time, the above method is not called.
Also, touchBegan: is only called when the first touch occurs (i.e. the initial holding touch) and touchEnded: is only called when all touches are removed, including the initial holding touch.
I'd like to know:
1) How to recognise the above gesture in Cocos2d v3?
2) If 1) isn't possible, would there be a way to do it with my own gesture recogniser, and how would I implement my own gesture recogniser into Cocos2d v3?
Turns out by default Cocos2d V3 only responds to a single touch by default.
The solution:
self.multipleTouchEnabled = TRUE;
This means now every new touch will call:
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
And every time a finger is lifted from the screen it will call:
-(void) touchEnded:(UITouch *)touch withEvent:(UIEvent *)event
Even if there are other touches continuing.
if you use void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) then you get each touch count using pTouches->count();

How to use touches began?

So I'm writing an app in which I have a custom UIView which contains a UIScrollView which contains a series of UIImageViews. I want to make it so that when I touch one of the UIImageViews within the UIScrollView, an event happens (for now, let's just say I print an NSLog() or something).
I know that there exists this function:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
But I'm not entirely sure how to use it. Which UIView should implement this function? Where would I call it exactly? Or does it get called automatically when something is touched? How do I find the correct UIImageView?
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event is already implemented by UIView (actually implemented by the UIResponder superclass, and by default it does nothing). this method is there for you to override in subclasses to do whatever you want to do.
this method is indeed called automatically whenever touches begin within the views boundary.
In your case using a UIButton with an image may be better.
instead of using touchesBegin: , subclass UIImageView, add Tap gesture to this new Class and use this Class instead of the ImageViews you are using on scrollView.

Is there a way to register all touchEnded events, no matter how long the touch was?

Is there a way to register all touch up through touchesEnded. It will only fire when there is a tap that lasts more than a second or two. Is there away to have it fire on all touch ups? It registers all touchesBegan.
Here is the simple code:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Touch Ended");
}
-touchesEnded:withEvent: gets called even for brief touches, like taps. You probably have something in your responder chain that's handling the touch. For example, scroll views will normally delay touches until they figure out whether the user is trying to scroll, and gesture recognizers can also delay touch events. Specifically, UIGestureRecognizer has a delaysTouchesEnded property that may be interfering with your code.
Multiple touches are disabled by default. If you want to receive multiple touch events you must set the a multipleTouchEnabled to YES of the view which you use. To do this in your ViewDidLoad just write self.view.multipleTouchEnabled= YES because it's just a property. Another issue may be connected with Magic Trackpad because it adds a delay before it decides that you have ended a touch.Try to disable it : >System Preferences>Personal>Universal Access>Mouse & Trackpad>Trackpad Options>Ignore Trackpad when mouse is present.

Trigger touchesEnded when dragging outside the UIView

I have a UIView subclass where I handle touches using touchesBegan, touchesMoved, touchesEnded.
I noticed that when I start a touch inside and then drag outside the UIView touchesEnded is not triggered, is there a way to have it called when I'm dragging outside the UIView frame?
Thanks
Use touchesCancelled instead.
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}
Pssibly it is calling the - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
Please check UIResponder Class Reference
touchesCancelled:withEvent:
Sent to the receiver when a system event (such as a low-memory
warning) cancels a touch event.
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
Parameters
touches
A set of UITouch instances that represent the touches for the ending phase of the event represented by event. event
An object representing the event to which the touches belong.
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. To forward the message to
the next responder, send the message to super (the superclass
implementation); do not send the message directly to the next
responder. For example,
[super touchesCancelled:touches withEvent:event];
If you override this method without calling super (a common use
pattern), you must also override the other methods for handling touch
events, if only as stub (empty) implementations. Availability
Available in iOS 2.0 and later.
You should still be getting touchesMoved in your viewController even you are outside of your view's frame. I would add array to your custom UIView which would keep touch objects that this view is assigned to and implement the following logic:
When you receive touchesBegan - add touch object to array for given UIView where touch coordinates match (you may have to iterate over all your subviews and match coordinates with frame to find the right one)
When you receive touchesMoved - remove touch from UIView's array for previous location and add it to UIView for current location if any
When you receive touchesEnded & touchesCancelled - remove touches from all UIViews arrays
When you remove or add touch object from your custom UIView array you may call your delegate methods (implement observer pattern) because at that point you know if it's really pressed or unpressed event. Keep in mind you may have many touch objects in one array so before calling your delegate check whether you added first object or deleted last one because that's the only case you should call your delegate.
I have implemented such solution in my last game, but instead of UIViews I had virtual buttons.

Resources