My problem is as follows: I am using pageViewControllers to create a tutorial/onboarding page for an app i'm creating. A left swipe gesture on the last (3rd) page of my tutorial should perform a segue.
This is what I have as of now, but it is giving me a key value coding-compliancy error. I have double, triple checked my outlets, and swipeView is very much so connected properly.
class GrowController: UIViewController {
#IBOutlet weak var swipeView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(swipeView)
createGesture()
}
func createGesture() {
let showReg = UISwipeGestureRecognizer(target: self, action: #selector(showRegister))
showReg.direction = .left
self.swipeView.addGestureRecognizer(showReg)
}
func showRegister(gesture: UISwipeGestureRecognizer) {
performSegue(withIdentifier: "showRegister", sender: self)
}
}
That is the controller for the actual UIViewController (the specific page that is being displayed)
now ive also tried messing around with some logic in my TutorialViewController which is the UIPageViewController controlling the swipes form page to page etc.
Logic for that here
class TutorialViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var viewControllerIndex: Int?
//Array of my pages to load (GrowController is page3)
lazy var tutorialArray: [UIViewController] = {
return [self.tutorialInstance(name: "page1"), self.tutorialInstance(name: "page2"), self.tutorialInstance(name: "page3")]
}()
private func tutorialInstance(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 firstViewController = tutorialArray.first {
setViewControllers([firstViewController], direction: .forward, animated: false, completion: nil)
}
}
// Scroll view
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
if view is UIScrollView {
view.frame = UIScreen.main.bounds
}
else if view is UIPageControl {
view.backgroundColor = UIColor.clear
}
}
}
// Page View Controller delegate functions
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = tutorialArray.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard tutorialArray.count > previousIndex else {
// Added this line just testing around, nothing happened here though.
performSegue(withIdentifier: "ShowRegister", sender: self)
return nil
}
return tutorialArray[previousIndex]
}
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = tutorialArray.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
guard nextIndex < tutorialArray.count else {
return nil
}
guard tutorialArray.count > nextIndex else {
return nil
}
return tutorialArray[nextIndex]
}
public func presentationCount(for pageViewController: UIPageViewController) -> Int {
return tutorialArray.count
}
public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first, let firstViewControllerIndex = tutorialArray.index(of: firstViewController) else {
return 0
}
return firstViewControllerIndex
}
}
Does is have something to do with the willTransitionTo pageView delegate method? I'm not familiar how to implement that, I have tried.
I thought that i could just add a subView to the Grow controller, put a swipe gesture in it, and perform a segue whenever the user swipes left from that page. As of right now, this code crashes the app upon loading of page3 (GrowController)
Any help GREATLY appreciated, I've been trying to figure this out for over a week and this is the second question on the topic i've posed. Thanks!
Don't use a UIPageViewController for this. That's very ironic, because I am usually the first to advise using UIPageViewController. But in this case it is doing too much of the work for you, and you cannot interfere in such a way as to customize it the way you're describing. You will need to use a simple paging UIScrollView; that way, you will be totally in charge of what happens, with fine-grained response thanks to the scroll view's delegate, and you'll have access to the underlying pan gesture recognizer and can modify its behavior.
Related
I’m having trouble with a UITableviewController embedded in a UIPageViewController…the system can’t distinguish between a swipe left to change pages and a swipe to delete an item in the UITableView. This particular UITableViewController happens to be on the last page of the PageViewController, so since swiping left doesn’t really do anything (nothing to the right) can I disable PageViewController from detecting swipes when current page == 3. The tricky part is I only want to ignore swipes to the left (so that the tableView reads the left swipe as a swipe to delete), whereas I want to still detect a swipe right so that the user can navigate back to page 2.
UIPageViewController code:
class WorkoutPageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
//var pageControl = UIPageControl()
var referenceToNewWorkoutKingVC: NewWorkoutKingViewController?
// MARK: UIPageViewControllerDataSource
lazy var orderedViewControllers: [UIViewController] = {
var viewControllers = [UIViewController]()
if referenceToNewWorkoutKingVC?.sessionType == goalieSessionString || referenceToNewWorkoutKingVC?.sessionType == refSessionString || referenceToNewWorkoutKingVC?.sessionType == coachSessionString || referenceToNewWorkoutKingVC?.sessionType == openSkateSessionString {
viewControllers = [self.newVc(viewController: "NewIceDataTableViewController"),
self.newVc(viewController: "NewHealthDataTableViewController")]
} else {
viewControllers = [self.newVc(viewController: "NewIceDataTableViewController"),
self.newVc(viewController: "NewHealthDataTableViewController"),
self.newVc(viewController: "NewShiftTableViewController")]
}
return viewControllers
}()
let impact = UIImpactFeedbackGenerator(style: UIImpactFeedbackGenerator.FeedbackStyle.medium)
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
// This sets up the first view that will show up on our page control
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
}
func newVc(viewController: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
// MARK: Delegate methods
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
let pageContentViewController = pageViewController.viewControllers![0]
referenceToNewWorkoutKingVC?.pageControl.numberOfPages = orderedViewControllers.count
referenceToNewWorkoutKingVC?.pageControl.currentPage = orderedViewControllers.index(of: pageContentViewController)!
}
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
//Haptic when pages switch, code from: https://www.hackingwithswift.com/example-code/uikit/how-to-generate-haptic-feedback-with-uifeedbackgenerator
impact.prepare()
impact.impactOccurred()
}
// MARK: Data source functions.
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
// User is on the first view controller and swiped left to loop to
// the last view controller.
guard previousIndex >= 0 else {
//return orderedViewControllers.last
// Uncommment the line below, remove the line above if you don't want the page control to loop.
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// User is on the last view controller and swiped right to loop to
// the first view controller.
guard orderedViewControllersCount != nextIndex else {
//return orderedViewControllers.first
// Uncomment the line below, remove the line above if you don't want the page control to loop.
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
}
Try this
func managePageControllerBounces(isEnable : Bool) {
for view in pageViewController.view.subviews {
if view is UIScrollView {
let scrollView = view as? UIScrollView
scrollView?.bounces = isEnable
}
}
}
Toggle bounces as per requirement
self.manegePageControllerBounces(isEnable: false)
Hope it's help to you....
I'm creating an onboarding app for New Patients of a physical therapy clinic. The new patient will answer questions on each view controller within the UIPageViewController and tap a button to go to the next question.
I followed a tutorial and set up my UIPageViewController PageVC along with 3 view controllers. PageVC currently changes pages by swiping, but I want to be able to navigate backward and forward through view controllers using two buttons that are subviews of PageVC itself. How do I accomplish this?
I like using UIPageViewController and want to understand it a bit more. If there is a more effective method besides using UIPageViewController to accomplish this same task I'm happy to consider it.
class PageVC: UIPageViewController, UIPageViewControllerDataSource {
private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.VCInstance(name: "BodyChart"),
self.VCInstance(name: "Symptoms"),
self.VCInstance(name: "HadSurgery")]
}()
private func VCInstance(name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewController(withIdentifier: name)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
guard orderedViewControllersCount != nextIndex else {
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController], direction: .forward, animated: true, completion: nil)
}
}
}
I think what you're looking for is here. But this is another way.
UIPageViewController has an instance method transition. The snippet below will move from the first to the second page child view controller.
pageViewController.transition(from: pageViewController.viewControllers[0], to: pageViewController.viewControllers[1], duration: 0.3, options: UIViewAnimationOptions.curveEaseInOut, animations: nil, completion: nil)
PageVC currently changes pages by swiping, but I want to be able to navigate backward and forward through view controllers using two buttons
Add your buttons to page content, then disable horizontal scrolling on PageVC's scrollview or disable views' user interaction in a mannered fashion.
When the user clicked in a cell it will go to the detail view controller here I post a notification with the selected index(object of a class). In detail view controller I used a container view. In this container view, I used a page view controller having two view controllers let's say A and B correspondingly. Both these two view controllers I created add observer method. But only 'A' view controller is registering for the notification. How can I get the selected index(object of a class) in B view controller..?
Code of detail View controller
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.post(name: Notification.Name(rawValue: mynotificationkey), object: nil, userInfo: ["object": self.treatobj])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "pageView2" {
if let destination = segue.destination as? PageViewController {
destination.treatmentObject = treatobj
}
}
}
code of First View Controller that its executing fine
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(display(notification:)), name: Notification.Name(rawValue: mynotificationkey), object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
}
func display(notification: Notification){
if let object = notification.userInfo {
if let obj = object["object"] {
treatObject = obj as! TreatMents
print(treatObject)
self.detailTitleLabel.text = treatObject.trtName
self.DesctextView.text = treatObject.desc1
}
}
}
code of second view controller that does not execute add observer
override func viewDidLoad() {
super.viewDidLoad()
about.text = treatObj.aboutkerala
//benifits = treatObj.benifits!
NotificationCenter.default.addObserver(self, selector: #selector(notfrecieved(notification:)), name: NSNotification.Name(rawValue: mynotificationkey), object: nil)
// Do any additional setup after loading the view.
}
func notfrecieved(notification: Notification) {
if let object = notification.userInfo {
if let obj = object["object"] {
print(obj)
treatObj = obj as! TreatMents
about.text = treatObj.aboutkerala
benifits = treatObj.benifits!
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
code of Page view controller
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var treatmentObject = TreatMents()
lazy var VCArray : [UIViewController] = {
return [self.VCInstance(name: "DescFisrtVC"),
self.VCInstance(name: "DescSecondVC"),
]
}()
private func VCInstance(name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: name)
}
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = VCArray.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return VCArray.last
}
guard VCArray.count > previousIndex else {
return nil
}
return VCArray[previousIndex]
}
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = VCArray.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
guard nextIndex < VCArray.count else {
return VCArray.first
}
guard VCArray.count > nextIndex else {
return nil
}
return VCArray[nextIndex]
}
// A page indicator will be visible if both methods are implemented, transition style is 'UIPageViewControllerTransitionStyleScroll', and navigation orientation is 'UIPageViewControllerNavigationOrientationHorizontal'.
// Both methods are called in response to a 'setViewControllers:...' call, but the presentation index is updated automatically in the case of gesture-driven navigation.
public func presentationCount(for pageViewController: UIPageViewController) -> Int {
return VCArray.count
}
public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first, let firstViewcontrollerIndex = VCArray.index(of: firstViewController) else {
return 0
}
return firstViewcontrollerIndex
}
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
if let firstVc = VCArray.first {
setViewControllers([firstVc], direction: .forward, animated: true, completion: nil)
}
// Do any additional setup after loading the view.
}
If you want to NotificationCenter then you need to load that class in memory first .
If you are added NotificationCenter in class but that class not loaded so this will be not working .
From the flow it looks to me that the two VCs in UIPageViewControllers didn't load yet when you are posting the notification.
Have a look at the explanation given in doc:
When defining a page view controller interface, you can provide the
content view controllers one at a time (or two at a time, depending
upon the spine position and double-sided state) or as-needed using a
data source. When providing content view controllers one at a time,
you use the setViewControllers(_:direction:animated:completion:)
method to set the current content view controllers. To support
gesture-based navigation, you must provide your view controllers using
a data source object.
So my guess is that since one page is loaded at a time, so your second controller didn't register for this event.
I have an objection on this process design using NSNotification, since from your code it looks to me that you want to evaluate your TreatMents objects on both screen when they gets load, IMHO you can either use Singleton concept (using session) or use KVO to fix this problem.
EDIT:
In PageViewController you implement these two functions:
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
that returns a VC from VCArray like:
return VCArray[previousIndex]
You also have treatmentObject in PageViewController, can you pass this variable to your two viewcontrollers while fetching it in above delegate functions like:
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = VCArray.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return VCArray.last
}
guard VCArray.count > previousIndex else {
return nil
}
let VC = VCArray[previousIndex] // <------ Check this out
VC.treatObj = self.treatmentObject; // <------ Check this out
return VC
}
Or you can also save your selected treatment in session and retrieve it in two view controllers.
I am using Swift 3.0 and have created a UIPageViewController currently with two pages (each one is a UIViewController). When I run the app, everything works fine, except that there are black spaces at the bottom and the right side of the app when the ViewControllers are shown. I also cannot see the page dots in the PageViewController. I have implemented the functions to place the dots on the screen:
func pageViewController(pageViewController: PageViewController,
didUpdatePageCount count: Int)
func pageViewController(pageViewController: PageViewController,
didUpdatePageIndex index: Int)
Layout
View Controller Inside the PageViewController
PageViewController Settings
Would anyone know how to fix the black borders around the pages and add the page dots?
Update
import UIKit
class PageViewController: UIPageViewController {
weak var pageDelegate: PageViewControllerDelegate?
private(set) lazy var orderedViewControllers: [UIViewController] = {
// The view controllers will be shown in this order
return [self.newViewController(name: "view1"),
self.newViewController(name: "view2"),
self.newViewController(name: "view3"),
self.newViewController(name: "view4"),
self.newViewController(name: "view5")]
}()
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
if let initialViewController = orderedViewControllers.first {
scrollToViewController(viewController: initialViewController, direction: UIPageViewControllerNavigationDirection.forward)
}
pageDelegate?.pageViewController(pageViewController: self, didUpdatePageCount: orderedViewControllers.count)
}
/**
Scrolls to the next view controller.
*/
func scrollToNextViewController() {
if let visibleViewController = viewControllers?.first,
let nextViewController = pageViewController(self, viewControllerAfter: visibleViewController) {
scrollToViewController(viewController: nextViewController, direction: UIPageViewControllerNavigationDirection.forward)
}
}
/**
Scrolls to the view controller at the given index. Automatically calculates
the direction.
- parameter newIndex: the new index to scroll to
*/
func scrollToViewController(index newIndex: Int) {
if let firstViewController = viewControllers?.first,
let currentIndex = orderedViewControllers.index(of: firstViewController) {
let direction: UIPageViewControllerNavigationDirection = newIndex >= currentIndex ? .forward : .reverse
let nextViewController = orderedViewControllers[newIndex]
scrollToViewController(viewController: nextViewController, direction: direction)
}
}
private func newViewController(name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewController(withIdentifier: "\(name)ViewController")
}
/**
Scrolls to the given 'viewController' page.
- parameter viewController: the view controller to show.
*/
private func scrollToViewController(viewController: UIViewController,
direction: UIPageViewControllerNavigationDirection = .forward) {
setViewControllers([viewController],
direction: direction,
animated: true,
completion: { (finished) -> Void in
// Setting the view controller programmatically does not fire
// any delegate methods, so we have to manually notify the
// 'pageDelegate' of the new index.
self.notifyPageDelegateOfNewIndex()
})
}
/**
Notifies '_pageDelegate' that the current page index was updated.
*/
func notifyPageDelegateOfNewIndex() {
if let firstViewController = viewControllers?.first,
let index = orderedViewControllers.index(of: firstViewController) {
self.pageDelegate?.pageViewController(pageViewController: self, didUpdatePageIndex: index)
}
}
}
// MARK: UIPageViewControllerDataSource
extension PageViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
// User is on the first view controller and swiped left to loop to
// the last view controller.
guard previousIndex >= 0 else {
return orderedViewControllers.last
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// User is on the last view controller and swiped right to loop to
// the first view controller.
guard orderedViewControllersCount != nextIndex else {
return orderedViewControllers.first
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
}
extension PageViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers: [UIViewController],
transitionCompleted completed: Bool) {
notifyPageDelegateOfNewIndex()
}
}
protocol PageViewControllerDelegate: class {
/**
Called when the number of pages is updated.
- parameter pageViewController: the PageViewController instance
- parameter count: the total number of pages.
*/
func pageViewController(pageViewController: PageViewController,
didUpdatePageCount count: Int)
/**
Called when the current index is updated.
- parameter pageViewController: the PageViewController instance
- parameter index: the index of the currently visible page.
*/
func pageViewController(pageViewController: PageViewController,
didUpdatePageIndex index: Int)
}
I had the same issue now, I've just solved that problem by changing the background color to white in the viewDidLoad() function
self.view.backgroundColor = .white
in my swift iOS app i would create a storyboard with two views. I want use the page view controller element, so, with one left / right swipe, the user can change the actual view. How can I do this?
IMPORTANT! I have searched several time for tutorials in the web. I have only found schema which allow to change images in the same image view. I don't want to change the image in the same image in the same view; i want change the entire view. I attach a image, to better explain.
Thank in advance]1
This explains how to create a paged view controller using storyboard:
Drag a UIPageViewController into storyboard and mark it as the initial view controller.
Then create a new UIPageViewController subclass - say call it TutorialPageViewController and assign it to the object you just dragged into storyboard.
Now drag in two new UIViewControllers into storyboard and create/assign a subclass for each, as you would do normally.
Give each of these two view controllers a Storyboard ID e.g RedViewController & GreenViewController.
Now add this code in your TutorialPageViewController which creates
and shows the correct view controller when you swipe:
TutorialPageViewController:
class TutorialPageViewController: UIPageViewController, UIPageViewControllerDataSource {
private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.newColoredViewController("RedViewController"),
self.newColoredViewController("GreenViewController")]
}()
private func newColoredViewController(color: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewControllerWithIdentifier("\(color)ViewController")
}
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .Forward,
animated: true,
completion: nil)
}
}
func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
guard orderedViewControllersCount != nextIndex else {
return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
}
See the article for more details and a tutorial on this.
https://spin.atomicobject.com/2015/12/23/swift-uipageviewcontroller-tutorial/
Update: Page Dots
Read from point 7 on this part 2 article that shows how to add a UIPageControl and change the dots on swipe:
https://spin.atomicobject.com/2016/02/11/move-uipageviewcontroller-dots/
#IBOutlet weak var pageControl: UIPageControl!
func tutorialPageViewController(tutorialPageViewController: TutorialPageViewController,
didUpdatePageCount count: Int) {
pageControl.numberOfPages = count
}
func tutorialPageViewController(tutorialPageViewController: TutorialPageViewController,
didUpdatePageIndex index: Int) {
pageControl.currentPage = index
}