I upgraded my iPad to 5.0 a couple days ago, and upgraded Xcode to 4.2 at the same time so I could continue to test my apps. Now I am having problems with touch code in several apps that worked with previous versions of Xcode.
I subclassed UIImageView to add some dragging features by overriding -(void)TouchesBegan
and -(void)TouchesMoved
. I did not override -(void)TouchesEnded
in the subclass, but handled that in the view controller for the view that contains the image view.
I pulled the subclassed UIImageView
into a new project for testing, and have narrowed down the issue to the fact that the parent UIView
(the template created by Xcode) does not seem to be forwarding touch events to the view controller (also created by Xcode).
If I add this to my subclass:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touches ended event in ImageToDrag");
[self.nextResponder touchesEnded:touches withEvent:event];
}
and this to my parent view's view controller:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touches ended event in ViewController");
}
when I let go of the image I am dragging around the screen, I get the "touches ended event in ImageToDrag"
, but not the log from the view controller.
However, if I intentionally skip over the view by doing this in the subclassed view:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touches ended event in ImageToDrag");
[[self.nextResponder nextResponder] touchesEnded:touches withEvent:event];
}
then I get both log entries.
The only explanation I can come up with is that for some reason, UIView
is consuming the touchesEnded
event and not passing it to the view controller.
I have verified that exclusiveTouch
is set to NO
, and userInteractionEnabled
is set to YES
on the parent view and the subclassed UIImageView
.
I have also tested compiling for iOS 5.0 and iOS 4.2, and deploying the test app to both an iOS 5 iPad and iOS 4.3.1 iPad.
The only way I have been able to get the touch event to the viewController
is by skipping over the view and using the double nextResponder
in the subclass. Although that method functions, it seems like a hack to me and I'm sure it will come back to bite me later.
Has anybody else seen this behavior? Is there any way for me to find out what the UIView
is doing with my touch events?
Thanks, Dan
I've been trying to track down the a similar issue for the last few hours. Finally managed to solve it with the help of this post
Actually it looks like I just managed to solve it, using the hint from https://devforums.apple.com/message/519690#519690
Earlier, I just forwarded the touchesEnded event to self.nextResponder. When I added touchesBegan, Moved, Cancelled handlers with similar implementations as the touchesEnded, the event seems to bubble up to the root view controller.
So I guess on iOS5, views discard touchesEnded events when they have not seen the relevant touchesBegan.
I didn't need to add Moved/etc., I just forwarded on TouchesBegan, and then TouchesEnded start working again!
Some touch handling did chance in iOS 5.0; especially if you re-link your application against the 5.0 SDK.
There's a section UIView's touch handling methods that says this:
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 (empy) implementations.
So if you do one, you need to do them all. I know UIKit started taking steps to make sure this was the case in 5.0.
So I'd start there - override all the methods on your view and see what happens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With