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