Swift UIPageViewController - for the requested spine location (UIPageViewControllerSpineLocationMin)

513 Views Asked by At

Here I Created UIPageViewController by programmatically. When I load more than one ViewController to UIPageViewController. App crashed.

Check my code below.

class PageVC: UIPageViewController {
    
    let colors = [UIColor.green, UIColor.red, UIColor.blue, UIColor.black]

    var pages: [UIViewController] = []
    
    override var spineLocation: UIPageViewController.SpineLocation {
        return .min
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.isDoubleSided = true
        
        colors.forEach({
            let page = UIViewController()
            page.view.backgroundColor = $0
            pages.append(page)
        })
        
        self.view.backgroundColor = UIColor.red
        
        self.setViewControllers(pages, direction: UIPageViewController.NavigationDirection.forward, animated: true, completion: nil)
    }
}

Getting Error like below.

enter image description here

Help me to fix this issue.

1

There are 1 best solutions below

0
On

I faced the same issue from another prospective. I was trying to change spine location from options when initializing the UIPageViewController. Following Apple Documentation i tried to wrap up the preferred spine location into an NSNumber and set it as the value for the spineLocation key in the options dictionary but the application always crash. Not sure why...

Actually, the only way i know to change the spine location programmatically is by returning the chosen one in the delegate method spineLocationFor orientation. You have to create another ViewController and add the custom PageViewController as a child. I know it's not the exact answer to your question but hope it helps. By code, using a UIPageViewController:

class ViewController: UIViewController {

private var pageController: UIPageViewController?

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

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    pageController?.view.frame = CGRect(x: 0,
                                        y: 0,
                                        width: self.view.frame.width,
                                        height: self.view.frame.height)
}

private func setupPageController() {
    self.pageController = UIPageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)
    self.pageController?.dataSource = self
    self.pageController?.delegate = self
    self.addChild(self.pageController!)
    self.view.addSubview(self.pageController!.view)

    self.pageController?.setViewControllers([UIViewController()], direction: .forward, animated: true, completion: nil)
            
    self.pageController?.didMove(toParent: self)
}
}

.

extension ViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate {

func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewController.SpineLocation {

    // handle orientation cases if needed
    // assuming you only support landscape:

    let initialVC = UIViewController()
    let initialVC2 = UIViewController()
    self.pageController?.setViewControllers([initialVC, initialVC2], direction: .forward, animated: true, completion: nil)
    pageController?.isDoubleSided = true
    return .mid
    }
}