问题
I have a UIPageViewController
that handles turning the pages of my "book". However, each book page is a ViewController
with a UIScrollView
as a subview
. The UIScrollView
is only able to scroll vertically due to the contentSize
. The problem is that while the user scrolls the scrollview
vertically, as the scrollview
is still scrolling/decelerating the user can not turn the page. A very easy way to see this is to scroll the page and then try to tap the edge of the view. This would normally change the page, and it does change the page when the scrollview
is not moving. However, when it is moving, the tap causes the scrollview to stop moving instead of turn the page.
How do I cancel the scrollviews
gestures if the UIPageViewController
is trying to use the gesture to turn the page by tapping or panning the page to cause the page turn animation?
For an example of the behavior I want to achieve, check the Twitter's official client on the iPhone. It's possible to swipe from Timeline to Discover while the feed is still decelerating from scrolling.
回答1:
A UIScrollView
scroll event will block other UIView
animations, so in the case of Twitter, they're probably canceling the scroll a split second before swiping the view. As you've asked in your question:
"How do I cancel the scrollviews gestures if the UIPageViewController is trying to use the gesture to turn the page by tapping or panning the page to cause the page turn animation?"
I'll suggest a workaround.
Instead of relying on the UIPageViewController
's inherent UIPanGestureRecognizer
, include your own UIPanGestureRecognizer
in the page view so that when a pan is detected in the appropriate section of the page and performed in the appropriate direction, that new UIPanGestureRecognizer
overrides the UIPageViewController
's UIGestureRecognizer
s and triggers the necessary actions. Specifically, you need to:
(1) Halt the scrolling animation using
CGPoint offset = scrollView.contentOffset;
[scrollView setContentOffset:offset animated:NO];
(2) Turn the page programmatically using
- (void)setViewControllers:(NSArray *)viewControllers direction:
(UIPageViewControllerNavigationDirection)direction animated:
(BOOL)animated completion:(void (^)(BOOL finished))completion;
so that both the scrolling animation is halted and the page flip is completed within one fluid pan gesture.
回答2:
UIGestureRecognizer
class has possibility to set dependencies on other gesture recognisers by using requireGestureRecognizerToFail: method.
In your case this method could be used in such way:
for (UIGestureRecognizer *gestureRecognizer in pageController.gestureRecognizers) {
for (ViewController *viewController in viewControllers) {
for (UIGestureRecognizer *gestureRecognizerForFail in viewController.scrollView.gestureRecognizers) {
[gestureRecognizerForFail requireGestureRecognizerToFail:gestureRecognizer];
}
}
}
回答3:
I had the same issue and I worked my way around... in my case I have pdf with zooming enabled. So I have for example:
[scrollView setMaximumZoomScale:6];
[scrollView setMinimumZoomScale:1];
when I initialize the controller and its scrollView, and just after that and every time I change orientation or page I change the zoom to fit the width of the page, only if the zoom is "far away"
CGFloat desiredWidth = scrollView.frame.size.width/pdfRect.size.width;
if (desiredWidth>[self zoomScale]) {
[scrollView setZoomScale:desiredWidth animated:YES];
}
I hope it helps
来源:https://stackoverflow.com/questions/13241736/uiscrollview-cancels-uipageviewcontroller-gestures-when-scrolling