I have the PageViewController
to ScrollViewController
by Swipe gesture.
It works, but I want to modify this and use the button to scroll.
The problem: There are three ViewControllers
in Storyboard but I don't know how to call parent class PageViewController
and ask to change the current view to the next one.
For example, ViewController1 button "nextView" -> ViewController2. In the case of call ViewController2 directly the PageViewController control can be broken. Is it correct?
What code should be for the UIButton of ViewController1?
PageViewController code:
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
lazy var orderedVC: [UIViewController] = {
return [self.newViewController(viewController: "ViewController1"),
self.newViewController(viewController: "ViewController2"),
self.newViewController(viewController: "ViewController3")]
}()
//Create the PageControl
var pageControl = UIPageControl()
func configurePageControl() {
pageControl = UIPageControl(frame: CGRect(x: 0, y: UIScreen.main.bounds.maxY - 50, width: UIScreen.main.bounds.width, height: 50))
...
self.view.addSubview(pageControl)
}
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
if let firstViewController = orderedVC.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
self.delegate = self
configurePageControl()
}
func newViewController(viewController: String) -> UIViewController {
return UIStoryboard(name: "Entry", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController:UIViewController) -> UIViewController? {
//Get index from the the views list BEFORE
guard let viewControllerIndex = orderedVC.firstIndex(of: viewController) else {return nil}
let previousIndex = viewControllerIndex - 1
//Limitations of the index
guard previousIndex >= 0 else {return nil}
guard orderedVC.count > previousIndex else {return nil}
return orderedVC[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController:UIViewController) -> UIViewController? {
//Get index from the the views list AFTER
guard let viewControllerIndex = orderedVC.firstIndex(of: viewController) else {return nil}
let nextIndex = viewControllerIndex + 1
//Limitations of the index
guard orderedVC.count != nextIndex else {return nil}
guard orderedVC.count > nextIndex else {return nil}
return orderedVC[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousVC: [UIViewController], transitionCompleted completed: Bool) {
let pageContentViewController = pageViewController.viewControllers![0]
self.pageControl.currentPage = orderedVC.firstIndex(of: pageContentViewController)!
}
}
Can use a custom protocol
and make your PageView controller the delegate for the view controllers.
protocol PageViewDelegate {
func previousPage()
func nextPage()
}
class ViewController: UIViewController {
var pageViewDelegate: PageViewDelegate?
@IBAction func previousButtonTapped(_ sender: Any) {
pageViewDelegate?.previousPage()
}
@IBAction func nextButtonTapped(_ sender: Any) {
pageViewDelegate?.nextPage()
}
}
class PageViewController: UIPageViewController, PageViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// After the viewControllers have been setup
self.viewControllers?.forEach {
if let controller = $0 as? ViewController {
controller.pageViewDelegate = self
}
}
}
func previousPage() {
//show previous page
}
func nextPage() {
//show next page
}
}
Read more about protocols here.