发布
社区首页 >问答首页 >如何使用带有现有UIPageViewController的按钮以编程方式幻灯片视图

如何使用带有现有UIPageViewController的按钮以编程方式幻灯片视图
EN

Stack Overflow用户
提问于 2018-01-01 16:21:57
回答 1查看 602关注 0票数 0

我正在开发一个有3个主视图的应用程序,为了让用户只需滑动(就像Tinder )就可以改变3个视图,我创建了一个PageViewController,它运行得很好。这个PageViewController的工作方式如下所示。

  1. 当用户点击“登录”或"SignUp“按钮时,它将指向PageViewController
  2. PageViewController将firstViewController设置为初始视图
  3. 在PageViewController中,它有3种方法,即“getFirst”(获取firstViewController)、“getSecond”(获取secondViewController)、“getThird”(获取thirdViewController)。

我还在每个视图的上部添加了按钮,希望用户能够点击这些按钮滑到其他视图,就像他们在滑动视图时所做的那样(这也像Tinder一样)。

所以在实验中,我在SecondViewController上添加了两个按钮。左边的是移动到FirstViewController,右边的是移动到ThirdViewController。然后,在SecondViewController文件中,我添加了"UIPageViewControllerDelegate“,并尝试为左侧按钮调用”getFirst“方法,并从PageViewController文件中调用右侧按钮的”getThird“方法。

但是当我点击左边的按钮时,我已经在getFirst文件中的“PageViewController”方法行中得到了这个错误消息(我可能也会得到右边按钮的相同错误)。

线程1:致命错误:在展开可选值时意外找到零

密码在下面。

PageViewController

代码语言:javascript
代码运行次数:0
复制
import UIKit

class PageViewController: UIPageViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setViewControllers([getFirst()], direction: .forward, animated: true, completion: nil)
        self.dataSource = self as UIPageViewControllerDataSource
    }
}


extension PageViewController : UIPageViewControllerDataSource {

    //FirstViewController
    @objc func getFirst() -> FirstViewController {
        return storyboard!.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
    }
    //SecondViewController
    @objc func getSecond() -> SecondViewController {
        return storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    }
    //ThirdViewController
    @objc func getThird() -> ThirdViewController {
        return storyboard!.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        if viewController.isKind(of: ThirdViewController.self) {
            // 3 -> 2
            return getSecond()
        } else if viewController.isKind(of: SecondViewController.self) {
            // 2 -> 1
            return getFirst()
        } else {
            // 1 -> end of the road
            return nil
        }
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        if viewController.isKind(of: FirstViewController.self) {
            // 1 -> 2
            return getSecond()
        } else if viewController.isKind(of: SecondViewController.self) {
            // 2 -> 3
            return getThird()
        } else {
            // 3 -> end of the road
            return nil
        }
    }
}

SecondViewController

代码语言:javascript
代码运行次数:0
复制
import UIKit
class SecondViewController: UIViewController, UIPageViewControllerDelegate {

    let pageHelper = PageViewController()
    override func viewDidLoad() {
        super.viewDidLoad()

        pageHelper.delegate = self
    }

    @IBAction func toFirstTapped(_ sender: Any) {
        pageHelper.getFirst()
    }
}

我遗漏了什么??也许我不能让它以这种方式工作(我不能从其他文件重用PageViewController?)

有人能帮帮我吗!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-01 19:33:36

首先,PageViewController实例化一个子控制器,该子控制器实例化一个PageViewController。这真的是个好主意吗?然后在您的toFirstTapped中,实例化一个FirstViewController,但是对它什么也不做。

如果你对它什么也不做,你希望它能起什么作用?

在任何情况下,请尝试以下方法:

代码语言:javascript
代码运行次数:0
复制
protocol PageNavigationDelegate : class {
    weak var pageController: PageViewController? { get set }
}

class PageViewController: UIPageViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.setViewControllers([getFirst()], direction: .forward, animated: true, completion: nil)
        self.dataSource = self as UIPageViewControllerDataSource
    }
}


extension PageViewController : UIPageViewControllerDataSource {

    func getFirst() -> FirstViewController {
        let controller = storyboard!.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
        controller.pageController = self
        return controller
    }

    func getSecond() -> SecondViewController {
        let controller = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
        controller.pageController = self
        return controller
    }

    func getThird() -> ThirdViewController {
        let controller = storyboard!.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
        controller.pageController = self
        return controller
    }

    @discardableResult
    func goToPreviousPage() -> Bool {
        let controller = self.viewControllers!.first!
        if controller.isKind(of: SecondViewController.self) {
            self.setViewControllers([getFirst()], direction: .reverse, animated: true, completion: nil)
            return true
        }

        if controller.isKind(of: ThirdViewController.self) {
            self.setViewControllers([getSecond()], direction: .reverse, animated: true, completion: nil)
            return true
        }

        return false
    }

    @discardableResult
    func goToNextPage() -> Bool {
        let controller = self.viewControllers!.first!
        if controller.isKind(of: FirstViewController.self) {
            self.setViewControllers([getSecond()], direction: .forward, animated: true, completion: nil)
            return true
        }

        if controller.isKind(of: SecondViewController.self) {
            self.setViewControllers([getThird()], direction: .forward, animated: true, completion: nil)
            return true
        }

        return false
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        if viewController.isKind(of: SecondViewController.self) {
            return getFirst()
        }

        if viewController.isKind(of: ThirdViewController.self) {
            return getSecond()
        }

        return nil
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

        if viewController.isKind(of: FirstViewController.self) {
            return getSecond()
        }

        if viewController.isKind(of: SecondViewController.self) {
            return getThird()
        }

        return nil
    }
}

class PageNavigationController : UIViewController, PageNavigationDelegate {
    var pageController: PageViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func goToPreviousController(_ sender: Any) {
        pageController?.goToPreviousPage()
    }

    @IBAction func goToNextController(_ sender: Any) {
        pageController?.goToNextPage()
    }
}

class FirstViewController: PageNavigationController {

}

class SecondViewController: PageNavigationController {

}

class ThirdViewController: PageNavigationController {

}

首先我们制定了一个协议。我们确保所有PageController的子控制器都能实现它。这样,他们就可以浏览到上一页和下一页。

接下来,我们创建具有goToPreviousPagegoToNextPage函数的扩展。当我们实例化每个控制器页面时,我们将self分配给它的协议实现变量。这样,控制器就可以访问PageViewController的方法。

最后,在我们的FirstSecondThird控制器中,我们只是告诉它按下按钮前进或后退。

就我个人而言,我更喜欢在数组中跟踪控制器,并且只返回代表中的控制器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48051275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档