Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISlider inside UIPageViewController

I have a PageViewController which is initialized like this:

self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
                          navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

On one of the pages, there's a UISlider.

My problem is that when I have transitionstyle set to UIPageViewControllerTransitionStyleScroll, it takes 150-200 ms before beginTrackingWithTouch is invoked on the slider. This behavior is not seen when I use UIPageViewControllerTransitionStylePageCurl, where the UISlider is selected instantly.

This means that unless the user waits a bit before dragging the slider (a video progress), the page will turn instead, which is far from ideal.

The Page curl animation does not meet the demands of the app, so any explanation or workaround is appreciated.

like image 856
Andreas Willadsen Avatar asked Jun 19 '13 07:06

Andreas Willadsen


2 Answers

Since with UIPageViewControllerTransitionStyleScroll gesture recognizers isn't available, you can use this:

for (UIView *view in pageViewController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
        UIScrollView *scrollView = (UIScrollView *)view;
        scrollView.delaysContentTouches = NO;
    }
}
like image 159
Sergey Alpeev Avatar answered Oct 20 '22 18:10

Sergey Alpeev


I solved this issue by add a pan gesture on UISlider and set:

self.sliderGesture.cancelsTouchesInView = NO;  // make touch always triggered

and implement delegate method like:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return otherGestureRecognizer.view.superview == self.parentViewController.view;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    // only receive touch in slider
    CGPoint touchLocation = [touch locationInView:self.view];
    return CGRectContainsPoint(self.slider.frame, touchLocation);
}
like image 2
yhlin Avatar answered Oct 20 '22 17:10

yhlin