ios - 在 UIPageViewControllers 中预加载所有 UIViewControllers (Swift)

标签 ios swift uiviewcontroller uipageviewcontroller

我目前在 Storyboard中有 3 个 UIViewController,我将它们连接到一个带有 ScrollView 的 UIPageViewController 中。但是,由于没有预加载 PageViewController 中的所有 UIViewController,我在中心 UIViewController 上初始化应用程序时遇到了一些问题。当用户首次打开应用 viewDidLoad 时,我使用 ScrollView contentOffset 显示中心 ViewController。

我已附上我在这里使用的代码:

    var currentIndex = 0
    var mainScrollView = UIScrollView()
    lazy var ViewControllerArray: [UIViewController] = {
        return [self.ViewControllerInstance(name: "RightVC"),
                self.ViewControllerInstance(name: "CenterVC"),
                self.ViewControllerInstance(name: "LeftVC")]

    }()

    private func ViewControllerInstance(name: String) -> UIViewController{

        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: name)

    }


    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataSource = self
        self.delegate = self
        if let CenterViewController = ViewControllerArray.first {
            setViewControllers([CenterViewController] , direction: .reverse, animated: false, completion: nil)
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        mainScrollView = view.subviews.filter { $0 is UIScrollView }.first as! UIScrollView
        mainScrollView.delegate = self
        mainScrollView.contentOffset.x = self.view.bounds.size.width * 2



    }




    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let ViewControllerIndex = ViewControllerArray.index(of: viewController) else {
            return nil
        }

        let PreviousIndex = ViewControllerIndex - 1
        currentIndex = ViewControllerIndex
        guard PreviousIndex >= 0 else {
            return nil
        }
        guard ViewControllerArray.count > PreviousIndex else {
            return nil

        }

        return ViewControllerArray[PreviousIndex]
    }


    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let ViewControllerIndex = ViewControllerArray.index(of: viewController) else {
            return nil
        }

        let NextIndex = ViewControllerIndex + 1
        currentIndex = ViewControllerIndex
        guard NextIndex < ViewControllerArray.count else {
            return nil
        }
        guard ViewControllerArray.count > NextIndex else {
            return nil

        }

        return ViewControllerArray[NextIndex]

    }
    // Control bounce @ DidScroll & EndDragging
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let lastPosition = scrollView.contentOffset.x
        if (currentIndex == ViewControllerArray.count - 1) && (lastPosition > scrollView.frame.width) {
            scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)

        } else if currentIndex == 0 && lastPosition < scrollView.frame.width {
            scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
        }
    }
    // ^^
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let lastPosition = scrollView.contentOffset.x
        if (currentIndex == ViewControllerArray.count - 1) && (lastPosition > scrollView.frame.width) {
            scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
        } else if currentIndex == 0 && lastPosition < scrollView.frame.width {
            scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
        }

    }

最佳答案

更新: 我使用变量 IntialOpen 作为系统的 bool 值来了解应用程序之前是否打开过,并且我还在公共(public)函数中添加了 If/else 语句。

public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let ViewControllerIndex = ViewControllerArray.index(of: viewController) else {
            return nil
        }
        let PreviousIndex = ViewControllerIndex - 1

        if !initialOpen {
            currentIndex = ViewControllerIndex
        }else{
            currentIndex = ViewControllerIndex + 1
            initialOpen = false
        }
        guard PreviousIndex >= 0 else {
            return nil
        }
        guard ViewControllerArray.count > PreviousIndex else {
            return nil
        }
        return ViewControllerArray[PreviousIndex]
    }


    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let ViewControllerIndex = ViewControllerArray.index(of: viewController) else {
            return nil
        }

        let NextIndex = ViewControllerIndex + 1


        if !initialOpen {
            currentIndex = ViewControllerIndex
        }else{
            currentIndex = ViewControllerIndex + 1
            initialOpen = false
        }
        guard NextIndex < ViewControllerArray.count else {
            return nil
        }
        guard ViewControllerArray.count > NextIndex else {
            return nil

        }

        return ViewControllerArray[NextIndex]

    }

如果这是应用程序第一次启动,则几乎可以强制它在第二页上打开。

关于ios - 在 UIPageViewControllers 中预加载所有 UIViewControllers (Swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44171230/

相关文章:

ios - layoutIfNeeded 在 iPad 上不起作用

ios - 在 map 中显示注释时出错

ios - 最初不可滚动的scrollView?

ios - 表格 View 单元格无法进入 numberOfRowsInSection

swift - 有没有办法可以识别与 viewController 关联的 .storyboard?

ios - 想知道如何知道仪器时间分析器中的符号,并且仅在 Xcode 中显示地址

ios - 如何将 Cocoa Touch 静态库链接到 MonoTouch 项目?

ios - SKView 集成到 UIViewController 中,UITextFields 滞后

ios - 从 ViewController 父类(super class)以编程方式添加 View 不会显示在前面

swift - 警告 : Attempt to present ViewController on ViewController which is already presenting ViewController