我已经实现了一个UIPageViewController
包含两页的内容。在最右边的页面上,我可以向右滑动,然后将页面向后拉,这样当我释放页面时,它就会弹回。当我向左滑动时,在左页面上也会发生同样的事情。(跳动就像到达野生动物园页面底部时发生的一样)
有没有办法禁用反弹效果?谢谢!
到目前为止,没有任何答案可以完全有效。他们都失败的边缘情况是:
在这种情况下,到目前为止,我所见过的每个解决方案都超出了页面0的范围。核心问题是底层API被破坏了,并开始报告相对于页面0的内容偏移,而没有调用我们的回调让我们知道它显示了另一个页面。在整个过程中,API仍然声称显示第1页,而实际上是显示在第0页上,而实际上是在第0页,而在第-1页上。
此设计缺陷的解决方法非常丑陋,但是这里是:
@property (weak,nonatomic) UIPageControl *pageControl;
@property (nonatomic,assign) BOOL shouldBounce;
@property (nonatomic,assign) CGFloat lastPosition;
@property (nonatomic,assign) NSUInteger currentIndex;
@property (nonatomic,assign) NSUInteger nextIndex;
- (void)viewDidLoad {
[super viewDidLoad];
...
self.shouldBounce = NO;
for (id testView in self.pageController.view.subviews) {
UIScrollView *scrollView = (UIScrollView *)testView;
if ([scrollView isKindOfClass:[UIScrollView class]]) {
scrollView.delegate = self;
// scrollView.bounces = self.shouldBounce;
}
}
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
return (NSInteger)self.currentIndex;
}
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{
id controller = [pendingViewControllers firstObject];
self.nextIndex = [viewControllers indexOfObject:controller];
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{
if(completed) {
// At this point, we can safely query the API to ensure
// that we are fully in sync, just in case.
self.currentIndex = [viewControllers indexOfObject:[pageViewController.viewControllers objectAtIndex:0]];
[self.pageControl setCurrentPage:self.currentIndex];
}
self.nextIndex = self.currentIndex;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
/* The iOS page view controller API is broken. It lies to us and tells us
that the currently presented view hasn't changed, but under the hood, it
starts giving the contentOffset relative to the next view. The only
way to detect this brain damage is to notice that the content offset is
discontinuous, and pretend that the page changed.
*/
if (self.nextIndex > self.currentIndex) {
/* Scrolling forwards */
if (scrollView.contentOffset.x < (self.lastPosition - (.9 * scrollView.bounds.size.width))) {
self.currentIndex = self.nextIndex;
[self.pageControl setCurrentPage:self.currentIndex];
}
} else {
/* Scrolling backwards */
if (scrollView.contentOffset.x > (self.lastPosition + (.9 * scrollView.bounds.size.width))) {
self.currentIndex = self.nextIndex;
[self.pageControl setCurrentPage:self.currentIndex];
}
}
/* Need to calculate max/min offset for *every* page, not just the first and last. */
CGFloat minXOffset = scrollView.bounds.size.width - (self.currentIndex * scrollView.bounds.size.width);
CGFloat maxXOffset = (([viewControllers count] - self.currentIndex) * scrollView.bounds.size.width);
NSLog(@"Page: %ld NextPage: %ld X: %lf MinOffset: %lf MaxOffset: %lf\n", (long)self.currentIndex, (long)self.nextIndex,
(double)scrollView.contentOffset.x,
(double)minXOffset, (double)maxXOffset);
if (!self.shouldBounce) {
CGRect scrollBounds = scrollView.bounds;
if (scrollView.contentOffset.x <= minXOffset) {
scrollView.contentOffset = CGPointMake(minXOffset, 0);
// scrollBounds.origin = CGPointMake(minXOffset, 0);
} else if (scrollView.contentOffset.x >= maxXOffset) {
scrollView.contentOffset = CGPointMake(maxXOffset, 0);
// scrollBounds.origin = CGPointMake(maxXOffset, 0);
}
[scrollView setBounds:scrollBounds];
}
self.lastPosition = scrollView.contentOffset.x;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
/* Need to calculate max/min offset for *every* page, not just the first and last. */
CGFloat minXOffset = scrollView.bounds.size.width - (self.currentIndex * scrollView.bounds.size.width);
CGFloat maxXOffset = (([viewControllers count] - self.currentIndex) * scrollView.bounds.size.width);
if (!self.shouldBounce) {
if (scrollView.contentOffset.x <= minXOffset) {
*targetContentOffset = CGPointMake(minXOffset, 0);
} else if (scrollView.contentOffset.x >= maxXOffset) {
*targetContentOffset = CGPointMake(maxXOffset, 0);
}
}
}
基本上,它记录每个滚动事件的偏移量。如果滚动位置在与滚动方向相反的方向上移动了一个不可能的距离(我随意选择了屏幕宽度的90%),则代码将假定iOS对我们说谎,并且行为就像过渡正确完成,将偏移量视为相对于新页面而不是旧页面。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句