How to stop 3d touch its interrupt other touch events? - ios

I have a view with touchesMoved event in current UIViewController , when touch move in screen it will draw something (free draw)
then I add a subView in the view and bind the UITapGestureRecognizer(set numberOfTapsRequired 2) with subview,
If double click is detect I will move the UIImageView to the click position.
When I try to draw again, something wrong is happen, the draw line is not smooth now (some line is not display)
Because of the 3D Touch in iPhone6s and 6s Plus, So I can't detect the tapCount in touchesEnded.What Shall I do?

The best way is stop the 3d touch while your app is launched :
As per the apple documentation you can see this here :Apple Docs
A user can turn off 3D Touch while your app is running, so read this property as part of your implementation of the traitCollectionDidChange: delegate method.
To ensure that all your users can access your app’s features, branch your code depending on whether 3D Touch is available. When it is available, take advantage of 3D Touch capabilities. When it is not available, provide alternatives such as by employing touch and hold, implemented with the UILongPressGestureRecognizer class.
Refer to iOS Human Interface Guidelines for ideas on how to enhance your app’s interactions for users with 3D Touch-capable devices while not leaving your other users behind.
BEST CODE:
#interface ViewController () <UIViewControllerPreviewingDelegate>
#property (nonatomic, strong) UILongPressGestureRecognizer *longPress;
For backward compatibility I’ll also add a long press gesture recogniser here. Should our sample app be run on a device without 3D Touch support, at least the preview can be brought up via a long press gesture.
We’ll check if 3D Touch is available using something like the following method. To complete the setup, I’ve also included a custom initialiser for the long press gesture.
- (void)check3DTouch {
// register for 3D Touch (if available)
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
[self registerForPreviewingWithDelegate:(id)self sourceView:self.view];
NSLog(#"3D Touch is available! Hurra!");
// no need for our alternative anymore
self.longPress.enabled = NO;
} else {
NSLog(#"3D Touch is not available on this device. Sniff!");
// handle a 3D Touch alternative (long gesture recognizer)
self.longPress.enabled = YES;
}
}
- (UILongPressGestureRecognizer *)longPress {
if (!_longPress) {
_longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(showPeek)];
[self.view addGestureRecognizer:_longPress];
}
return _longPress;
}

Related

Custom gestures from raw touch events on iOS

How do I receive raw touch events on iOS for creating my own gestures using my own state machine? I'm looking for the analogue of Android's MotionEvent for multi-touch gestures. I need to be able to draw on the background box, but I do not need OS components on this box.
iOS provides a gesture recognizer for defining custom gestures, and it defines UITouch objects that deliver to the application. However, the former is incapable of the implementing the complexity of my system, particularly at the efficiency I need, and the latter does preprocessing, such as to determine the tapCount. My system must itself decide whether a touch is a tap or not.
Additionally, I need to ascertain for myself whether multiple simultaneously-touching fingers form a gesture or not. I can't have iOS interpreting four-finger gestures input (exclusively) on top of my viewing area, though I could live with iOS interpreting five-finger gestures. It's okay for iOS to preempt control from my view if any finger of the gesture starts outside of the view.
The application is a gesturing alternative to the keyboard, so it would ideally be able to operate in the keyboard area, in case this affects the answer.
Is this possible on iOS? What's the approach? I'd like to write a simple program outputting touch events to prove it can be done. Thanks for your help!
UPDATE: I was largely able to answer the question by playing with the Multitouch Visualizer app. Each tap is registered as it occurs, and gestures of 4 fingers or fewer appear to be received without iOS interfering. iOS takes over for some 5 finger gestures, but only if they satisfy certain (unknown) initial characteristics. I don't know how this is done, but I imagine via UITouch events.

Overriding sendEvent in custom UIApplication to detect hardware keyboard event

I am developing an iPad app that needs to read input from a hardware keyboard. A primary user will be touching the screen normally while another user controls certain aspects of the app from a nearby Bluetooth keyboard that is paired with the iPad.
Overriding the keyCommands property in UIResponder has worked perfectly until now. But when we moved the app to Cocos2d (which uses its own responder chain) all the keyCommands stuff stopped working.
I tried subclassing UIApplication with an overridden sendEvent: method, something as simple as this:
#import "MyUIApplication.h"
#implementation MyUIApplication // subclass of UIApplication
-(void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
NSLog(#"Event detected");
}
As far as I can tell, this successfully detects all events except for hardware keyboard events, which appear to be totally ignored. Is there some way to detect these events without using keyCommands and UIKeyCommands?

Disabling iOS multitask gesture recognizer during game play

I am developing a game where the user could draw using up to 5 fingers, 1 finger for each line.
When multitask gesture is enabled and the user try to draw using more than 4 fingers from right to left, the gesture recognizer from iOS on iPad switch to another application.
How can I programmatically disable this recognizer when the user enters on my application?
There is no API for that.
There might be a way to consume the gesture, so it is not forwarded to the system, but I think the order of the messaging chain is in the other way.
You can only ask your users to disable the Multitasking Gestures in the System Preferences, under the General section. Not really great, I know.

iOS Touches Began susequent touches only arrive if first touch moved

I'm overriding the touches methods in a UIView for a piano app.
If I touch with one finger the iPhone or iPad I get -as expected- the touchesBegan callabck. And if I touch with a second finger I get that event in the touchesMoved callback. This is all fine, BUT I get the second (and third etc) callback ONLY if the first finger moves while I touch with the second one.
For a piano app this is a problem since I need to be able to touch really quickly.
Does anybody know a workarround for this? Is there an alternative than using touchesBegan/Moved/Ended methods?
Did you enable multitouch (setMultipleTouchEnabled:YES) for that UIView?

Screen blackout when performing Pinch Gesture on MPMoviePlayerController

I have this strange issue in iOS4 where in the Video which is playing in MPMoviePlayerController blacks out when the user performs certain kind of gestures over the screen. I'm simply creating a UIViewController and object for MPMoviePlayerController and then setting the View onto the UIViewController.
I want to ask if this issue is solvable or not, and whats the correct way of playing a streaming video on iPhone.
And if there is way that I can use a overlay view over MPMoviePlayerController and capture all gestures and pass on single taps or touches to MPMoviePlayerController for general functionality of MPMoviePlayerController and avoiding Gestures that is causing the issue.
Please help me solving the problem with the Best possible solution and please help me in elaborating the solution.
Apple embedded UIPinchGestureRecognizer in MPMoviePlayerViewController, but it can't be found in UIResponder.gestures property.
You can disable UIPinchGestureRecognizer embedded in touchesBegan method of MPMoviePlayerViewController.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
NSArray *array = touch.gestureRecognizers;
for (UIGestureRecognizer *gesture in array) {
if (gesture.enabled && [gesture isMemberOfClass:[UIPinchGestureRecognizer class]]) {
gesture.enabled = NO;
}
}
}
}
I had a similar problem and I just found the reason of my problem from the Apple's doc:
When you add a movie player’s view to your app’s view hierarchy, be sure to size the frame correctly, as shown here:
...
[player.view setFrame: myView.bounds]; // player's frame must match parent's
...
Now my pinches are not crashing my app.
I saw this issue and found a simple workaround.
The above gesture-nuking trick could not be used as we do not want to use MPMoviePlayerViewController (we have some custom controls when the video is not in fullscreen and would like to keep the smooth transition).
Symptoms (iOS 5.1):
When the user repeatedly opened a video in fullscreen, pinched it back out of fullscreen and then did the same with a new video the screen would go black the 5th time a video was started and entered fullscreen.
While the screen is blacked out it is possible to hide and show the status bar by single tapping, but no video or navigation bar appears.
Using the "Done" button in fullscreen instead of pinch it was possible to close fullscreen without any problems ever.
We allocate a fresh MPMoviePlayerController for each video and don't leak anything. This did not help.
Workaround:
When dismissing the view which had the MPMoviePlayerController view in it we set contentURL = nil on the player.
After that we have no problems with black screen on subsequent MPMoviePlayerController instances.
It seems there is some internal cleanup which is performed when using the "Done" button, but not when pinching to close fullscreen.
I hate this issue. What I have been able to find is that having full screen mode needs to have embedded control in order for the NSNotificationCenter to respond with the correct Notification. Sounds stupid and ridiculous, but this is what i've found in 4.0.

Resources