UIPageViewController中间转换如何通过编程实现?

4
我有一个包含n(n>>2)页的UIPageViewController。第一页是黄色的,第二页是蓝色的。当我从一页拖动到另一页时,我会得到一个漂亮的动画效果,如下图所示:

enter image description here

我尝试通过编程方式使页面从一个页面过渡到另一个页面。我获取了UIScrollView
for view:UIView in self.view.subviews as! [UIView] {
  if view.isKindOfClass(UIScrollView.self) {
    self.pageScrollView = view as? UIScrollView
  }
}

The I set the scroll position like this:

self.pageScrollView!.contentOffset.x = screenWidth - deltaX

结果如下:

结果如下:

enter image description here

滚动位置已更新,但下一个视图未加载。这就是为什么右侧有白色区域的原因。我知道可以使用setViewControllers设置下一页,但这将显示整个下一页。我想要的是像拖动一样部分地以编程方式显示下一页。

我知道这可以做到,因为Tinder应用程序已经在这样做了。当您在标题上进行平移手势时,页面视图控制器会非常流畅地切换页面。

enter image description here

如何在程序中模拟页面中间转换?

3个回答

2

如果涉及到分页,你不能半途而废。只要手指还在拖动,就可以实现翻页,但是一旦你抬起手指并停止拖动手势,控件将显示下一个UIViewController或已经被呈现的那个。

使用setViewControllersanimated:true,将平滑地从当前UIViewController过渡到下一个UIViewController,就像你用手指拖动视图一样:

.setViewControllers([allViewControllers[1]], direction: .Forward, animated: true, completion: nil)

如果您需要更加个性化的内容,可能需要使用UIScrollView而不是UIPageViewController,并自己设置内容。将pagingEnabled设置为true将使其表现得像带有“滚动”转换的UIPageViewController,但您也可以保持分页禁用并使用setContentOffset:(contentOffset,animated)的组合来使其按照您的喜好滚动,并使用delegate scrollViewWillEndDragging:(scrollView,withVelocity,targetContentOffset)来进行“分页”。
我创建了一个代码示例在这里,以说明我的意思。它是一个简单的UIScrollView,模仿了UIPageViewController,具有基本的视图分配/取消分配功能和半程程序化滚动的方法。

我如何获取在UIScrollView中显示的不同页面的生命周期事件? - user4788711
@stephan1001 你必须自己制作(UIPageViewController本身基本上是在UIScrollView上构建的)。一个简单的方法是保持所有视图(或视图控制器)的数组,然后使用scrollViewDidScroll委托来计算任何给定时间可见的视图。 floorf(bounds.origin.x / bounds.size.width)将为您提供第一个可见视图索引,而ceilf((bounds.origin.x + bounds.size.width) / bounds.size.width)将为您提供最后一个索引。从父视图中删除不在这些索引之间的所有视图,并添加那些在其中的视图。 - Rufel
1
@stephan1001 你试过了吗?当一个scrollView被包含在另一个scrollView中时,当你滚动内部的scrollView时,外部的scrollView会被锁定。它已经按照你想要的方式工作了;)。 - Rufel
1
@confile 在我提供的示例中没有使用,但如果您想在用户拖动时仅在scrollViewDidScroll中进行某些特定处理,则它可能会很方便,因为即使您使用setContentOffset以编程方式滚动视图,此回调也会被调用。否则,您可以忽略它。 - Rufel
1
如果您的标题视图没有控件,我会制作一个自定义视图,并将 touchEnabled 设置为 NO,然后将其放在 scrollView 上方,这样触摸就会在其中注册(不需要 pan 手势)。否则,它会变得更加复杂,您将不会拥有速度/反弹功能:使用 setContentOffset 在平移时不带动画,并在手势结束时找到最接近的偏移量:round(scrollView.contentOffset.x / self.view.bounds.size.width) * self.view.bounds.size.width,并将其设置为 scrollView 的 setContentOffset(带动画)。 - Rufel
显示剩余11条评论

1
基本上,在 Swift 中,你只需要写以下内容:
pageViewController.setViewControllers([yourVC()], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)

这里有一个好的教程:

https://www.youtube.com/watch?v=8bltsDG2ENQ


0

我也遇到了相同的问题,通过设置单个viewController进行转换来解决它。

就像在objective-c中一样

[self.pageControl setViewControllers:@[[self.viewControllers objectAtIndex:selectedPageIndex]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished) {

    }];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接