0
votes

I currently have 3 UIViewControllers in the storyboard and I connected them into one UIPageViewController with scrollView. However, I'm having some issues initializing the app on the center UIViewController due to not preloading all the UIViewControllers in the PageViewController. I'm using the scrollview contentOffset to show the center ViewController when the user first open the app viewDidLoad.

I have attached the code I'm using here:

    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)
        }

    }
1

1 Answers

0
votes

UPDATE: I used a variable IntialOpen as a bool for the system to understand whether the app was opened before and I also added If/else statement inside the public functions.

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]

    }

This worked by pretty much forcing it to open on the second page if its the first time the app has started.