在 Swift 中使用 UIPageViewController 水平滚动 ViewControllers 的按钮

Posted

技术标签:

【中文标题】在 Swift 中使用 UIPageViewController 水平滚动 ViewControllers 的按钮【英文标题】:Buttons to scroll horizontally ViewControllers with UIPageViewController in Swift 【发布时间】:2019-12-20 14:12:31 【问题描述】:

我通过滑动手势将PageViewController 转换为ScrollViewController。 它有效,但我想修改它并使用按钮滚动。

问题:Storyboard中有三个ViewControllers,但我不知道如何调用父类PageViewController并要求将当前视图更改为下一个。

例如,ViewController1 按钮“nextView” -> ViewController2。 在直接调用 ViewController2 的情况下,可以破坏 PageViewController 控件。对吗?

ViewController1的UIButton应该是什么代码?

PageViewController 代码:

class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource 

    lazy var orderedVC: [UIViewController] = 
        return [self.newViewController(viewController: "ViewController1"),
                self.newViewController(viewController: "ViewController2"),
                self.newViewController(viewController: "ViewController3")]
    ()

    //Create the PageControl
    var pageControl = UIPageControl()
    func configurePageControl() 
        pageControl = UIPageControl(frame: CGRect(x: 0, y: UIScreen.main.bounds.maxY - 50, width: UIScreen.main.bounds.width, height: 50))
        ...
        self.view.addSubview(pageControl)
    

    override func viewDidLoad() 
        super.viewDidLoad()

        self.dataSource = self
        if let firstViewController = orderedVC.first 
            setViewControllers([firstViewController],
                               direction: .forward,
                               animated: true,
                               completion: nil)
        
        self.delegate = self
        configurePageControl()
    

    func newViewController(viewController: String) -> UIViewController 
        return UIStoryboard(name: "Entry", bundle: nil).instantiateViewController(withIdentifier: viewController)
    

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

        //Get index from the the views list BEFORE
        guard let viewControllerIndex = orderedVC.firstIndex(of: viewController)   else return nil
        let previousIndex = viewControllerIndex - 1

        //Limitations of the index
        guard previousIndex >= 0    else return nil
        guard orderedVC.count > previousIndex  else return nil

        return orderedVC[previousIndex]
    

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

        //Get index from the the views list AFTER
        guard let viewControllerIndex = orderedVC.firstIndex(of: viewController)   else return nil
        let nextIndex = viewControllerIndex + 1

        //Limitations of the index
        guard orderedVC.count != nextIndex else return nil
        guard orderedVC.count > nextIndex  else return nil

        return orderedVC[nextIndex]
    

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousVC: [UIViewController], transitionCompleted completed: Bool) 
        let pageContentViewController = pageViewController.viewControllers![0]
        self.pageControl.currentPage = orderedVC.firstIndex(of: pageContentViewController)!
    

【问题讨论】:

创建一个protocol 并让您的 PageViewController 遵守它。将该协议类型的委托属性添加到视图控制器,并让它们在按下按钮时调用该委托上的函数。 【参考方案1】:

可以使用自定义 protocol 并使您的 PageView 控制器成为视图控制器的委托。

protocol PageViewDelegate 
    func previousPage()
    func nextPage()


class ViewController: UIViewController 
    var pageViewDelegate: PageViewDelegate?
    @IBAction func previousButtonTapped(_ sender: Any) 
        pageViewDelegate?.previousPage()
    
    @IBAction func nextButtonTapped(_ sender: Any) 
        pageViewDelegate?.nextPage()
    


class PageViewController: UIPageViewController, PageViewDelegate 
    override func viewDidLoad() 
        super.viewDidLoad()
        // After the viewControllers have been setup
        self.viewControllers?.forEach 
            if let controller = $0 as? ViewController 
                controller.pageViewDelegate = self
            
        
    
    func previousPage() 
        //show previous page
    
    func nextPage() 
        //show next page
    

阅读有关协议的更多信息here。

【讨论】:

所以我在 PageViewController 类之外创建了协议并调用了 print("test")。从 ViewController1 调用。 pageViewDelegate?.previousPage() 。不工作。奇怪。 //显示上一页 基本上就是我要问的这个地方。 创建视图控制器时,您必须将其delegate 属性设置为接收页面视图控制器

以上是关于在 Swift 中使用 UIPageViewController 水平滚动 ViewControllers 的按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何在OC中使用Swift如何在Swift中使用OC

swift 优雅地处理Swift中可本地化的字符串。注意:此代码在Swift 2中,需要在现代Swift中使用更新。

在 Swift 项目中使用 Objective C 类中的 Swift 类

在 Swift 项目中使用 Objective C 类中的 Swift 类

如何在 Swift 中使用 Apple 地图 - 你必须使用 C 还是 Swift 可以?

swift 在swift中使用javascriptcore