Swift - UIPageViewController总是重复第二个ViewController

时间:2014-09-11 18:55:36

标签: ios swift uipageviewcontroller

设置:我尝试创建一个带有嵌入式UIPageViewController的ViewController,其中有4个页面,每个页面都是自己的ViewController。

问题:滚动时总是重复第二个视图。例如,使用View1,View2,View3,View4滚动显示View1,View2,View2,View3,View4然后向后滚动,即使页面控件准确,也可以查看View4,View3,View3,View2,View1。

我在线查看了许多教程,包括答案herehere

这是我的页面视图控制器类:

import UIKit

class HostGamePageViewController: ROLViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {

  // Constants
  let ViewControllers: NSArray = ["HostGameTest1", "HostGameTest2", "HostGameTest3", "HostGameTest4"]

  // Properties
  var pageViewController: UIPageViewController!
  var currentViewController: String!

  // UI
  @IBOutlet var pageControl: UIPageControl!

  override func viewDidLoad() {
    super.viewDidLoad()

    pageViewController = storyboard?.instantiateViewControllerWithIdentifier("HGPageViewController") as? UIPageViewController
    pageViewController.delegate = self
    pageViewController.dataSource = self

    let startingViewController = viewControllerAtIndex(0)!
    pageViewController.setViewControllers([startingViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: {done in })

    addChildViewController(pageViewController)
    view.addSubview(pageViewController.view)
    pageViewController.view.frame = view.bounds
    pageViewController.didMoveToParentViewController(self)
    view.gestureRecognizers = pageViewController.gestureRecognizers

    // Setup page controls
    pageControl.numberOfPages = ViewControllers.count
    view.bringSubviewToFront(pageControl)
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  // Get the index of the current page view
  func indexOfViewController() -> Int {
    if currentViewController != nil {
      return ViewControllers.indexOfObject(currentViewController)
    }

    return NSNotFound
  }

  // Get the view controller of the given index
  func viewControllerAtIndex(index: Int) -> UIViewController? {
    if ViewControllers.count == 0 || index >= ViewControllers.count {
      return nil
    }

    pageControl.currentPage = index
    currentViewController = ViewControllers[index] as String

    return storyboard?.instantiateViewControllerWithIdentifier(currentViewController) as? ROLViewController
  }

  // Handle clicks on the page control
  @IBAction func pageControlClick(sender: UIPageControl) {
    var direction: UIPageViewControllerNavigationDirection

    if sender.currentPage < indexOfViewController() {
      direction = UIPageViewControllerNavigationDirection.Forward
    } else {
      direction = UIPageViewControllerNavigationDirection.Reverse
    }

    if let viewController = viewControllerAtIndex(sender.currentPage) {
      pageViewController.setViewControllers([viewController], direction: direction, animated: false, completion: nil)
    }
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    var index = indexOfViewController()

    if index == 0 || index == NSNotFound {
      return nil
    }

    index--
    return viewControllerAtIndex(index)
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    var index = indexOfViewController()

    if index == NSNotFound {
      return nil
    }

    index++
    if index == ViewControllers.count {
      return nil
    }

    return viewControllerAtIndex(index)
  }

}

这是我的故事板截图的链接: http://f.cl.ly/items/0V3W133Q34170q39393Q/Image%202014-09-11%20at%2011.49.44%20AM.png

我是否错误地设置了dateSource?我在某地读到UIPageViewController通过将动画变为false来做一些缓存,这是假定的修复,对我没有做任何事情。任何帮助将非常感激。谢谢!

1 个答案:

答案 0 :(得分:5)

我有一个非常类似的问题(不使用swift,在obj-c中,有3个视图控制器,中间的一个重复一次:“0,1,1,2”)。原来它是关于页面视图控制器数据源方法......

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;

我还没有真正深入研究过swift(也没有兴趣这么做),但伪读你的代码让我觉得你限制了的限制 UIPageViewControllerDataSource 作为 UIPageViewControllerDataSource 的控制器中使用变量之前的“和之后”关键方法(swift-wise),正是我改变了并修复了问题。

我没有最好的英语,但我希望你理解最后的陈述。我使用的修复程序基于this tutorial。在我的例子中,视图控制器我在所有3个案例中使用了“UINavigationViewControllers”,所以我创建了一个具有属性的“NavigationWrapperViewController”:

@property(assign, nonatomic) NSUInteger index;

然后,当检查关键数据源方法中的边界限制时(仅显示一个,对另一个使用相同的技术):

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
   NSUInteger indice = ((NavigationWrapperViewController*)viewController).index;
   if ((indice == 0) || (indice == NSNotFound)) {
       return nil;
   }    
   return [self viewControllerAtIndex:(--indice)];
}

viewControllerAtIndex 中实例化视图控制器时,不要忘记在返回之前正确设置该属性:

NavigationWrapperViewController *wrapperViewController = [self.storyboard instantiateViewControllerWithIdentifier:self.ViewControllers[index]];
wrapperViewController.index = index;

return wrapperViewController;

细微差别在于显示的视图控制器的索引由当前视图控制器存储(使用一个简单的包装器,该类完全是为了这个目的,它只是在他的.h文件中有一个属性实现) UIPageViewControllerDataSource负责类。

这解决了我的问题,也许是某种线程相关的问题影响了当前的视图控制器索引,这个索引被提取并导致了整个 - 重复的视图控制器 - 问题。

希望如果你愿意尝试它会有所帮助!