在 Swift 中使用 PageViewController 设置 NSTimer

Setting up NSTimer with PageViewController in Swift

我最近设置了一个 ContainerView 和一个 PageViewController 循环浏览视图(图像)作为我拥有的 TableView 顶部的一种横幅。现在,我很难将其连接到 NSTimer(以便它会自动循环通过 views/images)。一切正常,除了我试图连接的计时器。我尝试转换一些 Objective-C tutorials/SO 问题,但仍然遇到困难。

我看过这个:Set timer to UIPageViewController,但我根本无法让提供的代码为我工作(也没有任何变体)。

请参阅下面的代码:

class ImageSwapViewController: UIPageViewController {

    private(set) lazy var orderedViewControllers: [UIViewController] = {
        return [self.newColoredViewController("First"),
        self.newColoredViewController("Second"),
        self.newColoredViewController("Third")]
    }()

    private func newColoredViewController(order: String) -> UIViewController {
        return UIStoryboard(name: "Main", bundle: nil) .
        instantiateViewControllerWithIdentifier("\(order)ViewController")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        self.dataSource = self

        if let firstViewController = orderedViewControllers.first {
        setViewControllers([firstViewController],
            direction: .Forward,
            animated: true,
            completion: nil)
    }

        NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(ImageSwapViewController.animation), userInfo: nil, repeats: true)
    }

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

    func animation() {
        [NEED HELP WITH WHAT GOES HERE]
    }
}

extension ImageSwapViewController : UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController,
        viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
            guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
                return nil
            }

            let previousIndex = viewControllerIndex - 1

            guard previousIndex >= 0 else {
                return orderedViewControllers.last
            }

            guard orderedViewControllers.count > previousIndex else {
                return nil
            }

            return orderedViewControllers[previousIndex]
    }

    func pageViewController(pageViewController: UIPageViewController,
        viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
            guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
                return nil
            }

            let nextIndex = viewControllerIndex + 1
            let orderedViewControllersCount = orderedViewControllers.count

            guard orderedViewControllersCount != nextIndex else {
                return orderedViewControllers.first
            }

            guard orderedViewControllersCount > nextIndex else {
                return nil
            }

            return orderedViewControllers[nextIndex]
    }

}

非常感谢任何帮助。

一些注意事项:

1) 大意是需要在一些合理的地方设置一个定时器--viewWillAppear是一个常用的位置,记得让它失效当视图不再显示时(如 viewWillDisappear)。否则可能会导致内存增长,因为 运行 循环拥有对目标的强引用——在本例中为 self。我建议将您的 NSTimer.scheduledTimer... 调用移动到 viewWillAppear.

2) 上面的 animation 代码非常简单。基本上,您需要获取当前 "page",找出下一个 "page" 应该是什么,然后让您的 UIPageViewController 显示下一个 "page".

func animation() {
    guard let currentViewController = viewControllers?.first else {
        return
    }

    // Use delegate method to retrieve the next view controller
    guard let nextViewController = pageViewController(self, viewControllerAfterViewController: currentViewController) else {
        return
    }
    setViewControllers([nextViewController], direction: .Forward, animated: true, completion: nil)
}

您还可以稍微简化 beforeafter 方法:

func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    guard let i = orderedViewControllers.indexOf(viewController) else {
        return nil
    }
    let nextIndex = (i + 1) % AutoAnimatingPageViewController.colors.count
    return orderedViewControllers[nextIndex]
}

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    guard let i = orderedViewControllers.indexOf(viewController) else {
        return nil
    }
    let prevIndex = (i - 1) < 0 ? AutoAnimatingPageViewController.colors.count - 1 : (i - 1)
    return orderedViewControllers[prevIndex]
}