Reusable ViewControllers in ScrollView Pass By Reference

I am attempting to create a

UIScrollView
with infinitely many horizontally scrolling pages. I plan to use instances of several reusable cached ViewControllers to fill the pages. To achieve this I am trying to create a similar effect to UIPageViewController by using a
beforeViewController
a
currentViewController
and an
afterViewController
to fill the the three positions as the user scrolls so there is always one viewController before and after the current one the user is looking at to scroll to.

I would like to keep setting these instances equal to varying viewControllers from my cache but as I scroll back and forth eventually I am left with an empty ViewController. I believe it is caused by the passed by reference nature of the ViewController and setting one equal to the other.

Below is the code I have created is there any way to improve the functionality. Thank you in advance for your help.



import UIKit
   
    class ViewController: UIViewController,UIScrollViewDelegate {
   
        var previousOffset:CGFloat = 0
       
        var viewControllers:[UIViewController] = [UIViewController](){
            didSet{
                print("viewControllers.count: \(viewControllers.count)")
            }
        }
       
        var beforeViewController:UIViewController?
        var currentViewController:UIViewController?
        var nextViewController:UIViewController?
       
        var scrollView:UIScrollView = {
            let scrollView = UIScrollView()
            scrollView.isPagingEnabled = true
            scrollView.backgroundColor = UIColor.lightGray
            scrollView.translatesAutoresizingMaskIntoConstraints = false
            return scrollView
        }()
       
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            scrollView.delegate = self
            //3 Pages
            scrollView.contentSize = CGSize(width: 3 * self.view.bounds.width, height: self.view.bounds.height)
           
            self.view.addSubview(scrollView)
           
            NSLayoutConstraint.activate([
                scrollView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0),
                scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0),
                scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0),
                scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
                ])
           
            currentViewController = getViewController()
            addViewController(viewController: currentViewController!, index: 0) { (view) in
                view.backgroundColor = UIColor.green
            }
           
            nextViewController = getViewController()
            addViewController(viewController: nextViewController!, index: 1) { (view) in
                view.backgroundColor = UIColor.purple
            }
           
        }
       
        func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            let currentPage = scrollView.contentOffset.x/scrollView.bounds.width
            print("current page: \(currentPage)")
            if scrollView.contentOffset.x > previousOffset{
                print("User scrolled Forward")
                scrolledForwards(currentPage: Int(currentPage))
            }else if scrollView.contentOffset.x < previousOffset{
                print("User scrolled backwards")
                scrolledBackwards(currentPage: Int(currentPage))
            }
            previousOffset = scrollView.contentOffset.x
        }
   
        func getViewController()->UIViewController{
            let unusedViewControllers:[UIViewController] = self.viewControllers.filter({return $0.parent == nil})
            if let unusedViewController = unusedViewControllers.first{
                print("reusing viewController: \(viewControllers.count)")
                print("reusing viewController: \(unusedViewController.description)")
                return unusedViewController
            }else{
                let newViewController = UIViewController()
                self.viewControllers.append(newViewController)
                print("creating new viewController")
                return newViewController
            }
        }
       
        func addViewController(viewController:UIViewController,index:Int, completion: ((UIView)->Void)? = nil){
            self.willMove(toParent: viewController)
            self.addChild(viewController)
            guard let view = viewController.view else{
                removeViewController(viewController: viewController)
                fatalError("view controller sent without a view")
            }
            self.scrollView.addSubview(view)
            viewController.didMove(toParent: self)
           
            let offset = self.view.bounds.width * CGFloat(index)
           
            view.translatesAutoresizingMaskIntoConstraints = false
     
            NSLayoutConstraint.activate([
                view.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0),
                view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: offset),
                view.heightAnchor.constraint(equalTo: scrollView.heightAnchor, constant: 0),
                view.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: 0)
                ])
           
            if let completion = completion{
             completion(view)
            }
           
        }
       
        func removeViewController(viewController:UIViewController?, completion: ((UIView)->Void)? = nil){
            viewController?.willMove(toParent: nil)
            viewController?.view.removeFromSuperview()
            viewController?.removeFromParent()
           
           
            if let completion = completion{
                completion(view)
            }
           
        }
   
       
        func scrolledForwards(currentPage:Int = 0){
            removeViewController(viewController: beforeViewController)
            let index = currentPage + 1
            self.beforeViewController = self.currentViewController
            self.currentViewController = self.nextViewController
            print("index: \(index)")
            if index > 2{
                print("There is no more forwards")
                return
            }
            self.nextViewController = getViewController()
           
                    if nextViewController?.parent == nil{
                        let index = currentPage + 1
                        self.addViewController(viewController: nextViewController!, index: index) { (view) in
                            view.backgroundColor = .magenta
                        }
                    }
     
   
        }
       
        func scrolledBackwards(currentPage:Int = 0){
   
            let index = currentPage - 1
           
            removeViewController(viewController: nextViewController)
            nextViewController = currentViewController
            currentViewController = beforeViewController
            print("index: \(index)")
            if index < 0{
                print("There is no more backwards")
                return
            }
            beforeViewController = getViewController()
   
            currentViewController?.view.backgroundColor = UIColor.brown
           
            if beforeViewController?.parent == nil{
                self.addViewController(viewController: beforeViewController!, index: index) { (view) in
                    view.backgroundColor = .cyan
                }
            }
           
        }
       
       
   
    }