Monday, April 18, 2016

Disable Swipe gesture in Selected views of UIPageViewController

I used UIPageViewController for the seamless navigation of tabs through swipe gestures.Since UIPageViewController seems good for swipe gesture navigation i used this controller through out the application.

It works like a charm until i got a need to implement a custom slider inside a view of UIPageViewController.


Design of the screen is as below:




Problem was when i intend to swipe the play field slider either forward or backward,the entire screen moves,page controller eats the swipe gesture and thinks it has to navigate to next screen or previous screen.But my intention was i would like to forward the song for a few seconds or reverse for few seconds.


I tried to solve this problem by many methods.Every attempts failed but one simple and efficient solution worked wonders to me.


I created one Pan Gesture Recognizer with no handle method and added to the Slider view initially.And set CancelsTouchesInView to false.


Code snippet in Xamarin


            UIPanGestureRecognizer panGesture=new        UIPanGestureRecognizer();
            panGesture.CancelsTouchesInView=false;

            PlayfieldSlider.AddGestureRecognizer(panGesture);
           PlayfieldSlider.thumbButton.AddGestureRecognizer(panGesture);

I added the pan gesture only to the thumb portion of slider.Thumb is the one which has play/pause button on the slider of any music player.Idea is when user holds thumb and drags along the slider the page controller does not react whereas if user slides anywhere even on the slider area also makes the page to move to another screen.


Explanation


Referhttp://stackoverflow.com/questions/13042632/what-really-happens-when-call-setcancelstouchesinview

suppose you have a view with a pan gesture recognizer attached, and you have these methods in your view controller:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"touchesBegan");
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"touchesMoved");
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"touchesEnded");
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"touchesCancelled");
}

- (IBAction)panGestureRecognizerDidUpdate:(UIPanGestureRecognizer *)sender {
    NSLog(@"panGesture");
}
And of course the pan gesture recognizer is configured to send the panGestureRecognizerDidUpdate: message.
Now suppose you touch the view, move your finger enough for the pan gesture to be recognized, and then lift your finger. What does the app print?
If the gesture recognizer has cancelsTouchesInView set to YES, the app will log these messages:
touchesBegan
touchesMoved
touchesCancelled
panGesture
panGesture
(etc.)
You might get more than one touchesMoved before the cancel.
So, if you set cancelsTouchesInView to YES (the default), the system will cancel the touch before it sends the first message from the gesture recognizer, and you won't get any more touch-related messages for that touch.
If the gesture recognizer has cancelsTouchesInView set to NO, the app will log these messages:
touchesBegan
touchesMoved
panGesture
touchesMoved
panGesture
touchesMoved
panGesture
(etc.)
panGesture
touchesEnded
So, if you set cancelsTouchesInView to NO, the system will continue sending touch-related messages for the gesture touch, interleaved with the gesture recognizer's messages. The touch will end normally instead of being cancelled (unless the system cancels the touch for some other reason, like the home button being pressed during the touch).

No comments:

Post a Comment