Rowan Stanley Rowan Stanley - 6 months ago 174
Swift Question

have a UINavigationBar title for each page in PageViewController

I have set up my pageViewController (embedded in a NavigationController) with an array of ViewControllers to use as the pages (seen below):

`
class PageViewController: UIPageViewController {

var arrayIndex: Int = 0
var navigationBar = UINavigationBar()
var pageControl = UIPageControl.self





override func viewDidLoad() {
super.viewDidLoad()

dataSource = self



if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .Forward,
animated: true,
completion: nil)
}




}


// set up & order all view controllers

private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.newDayViewController("monday"),
self.newDayViewController("tuesday"),
self.newDayViewController("wednesday"),
self.newDayViewController("thursday")//,
self.newDayViewController("friday"),
self.newDayViewController("saturday"),
self.newDayViewController("sunday")
]


}()






// instantiate view controllers above that contain 'day' (easiest method to differentiate from other controllers)

private func newDayViewController(day: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil) .
instantiateViewControllerWithIdentifier("\(day)")
}


func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if (!completed) {
return
}

arrayIndex = Int(pageViewController.viewControllers!.first!.view.restorationIdentifier!)!


switch arrayIndex {

case 0:
navigationBar.topItem!.title = "Monday"
break

case 1:
navigationBar.topItem!.title = "Tuesday"
break

case 2:
navigationBar.topItem!.title = "Wednesday"
break

case 3:
navigationBar.topItem!.title = "Thursday"
default:
navigationBar.topItem!.title = "Timetable"


}
}








}


extension PageViewController: UIPageViewControllerDataSource {




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 orderedViewControllers.last
}

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




//MARK: - determine which viewController the user is on



guard orderedViewControllersCount != nextIndex else {
return orderedViewControllers.first
}

guard orderedViewControllersCount > nextIndex else {
return nil
}

return orderedViewControllers[nextIndex]
}

func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return orderedViewControllers.count
}

func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
guard let firstViewController = viewControllers?.first,
firstViewControllerIndex = orderedViewControllers.indexOf(firstViewController) else {
return 0
}

return firstViewControllerIndex
}


}

`


I am wondering how I could have it so that when the user is swiping through the pageViews, the UINavigationBar's title changes to the title of the view they are looking at ? e.g : When the user is looking at the mondayViewController, the title is monday and they can swipe to tuesday and the title will change etc.

Any suggestions are welcome

Thanks!

Answer

There are some errors in your code, first of all there isnt a UIPageViewControllerDelegate, so the delegates method will never be called.

Then, I dont know if your PageViewController really have a UINavigationController. To ensure that you can embed it by selecting your PageViewController and make the same thing as maded in picture:

enter image description here

so you can see in your storyboard both UINavigationController and UIPageViewController like this:

enter image description here

After you have all your day UIViewController created with each storyboard id, for example for monday:

enter image description here

you can modify you code like the code below:

   import UIKit
    class PageViewController: UIPageViewController,UIPageViewControllerDelegate {
        var arrayIndex: Int = 0
        var pageControl = UIPageControl.self
        private(set) lazy var orderedViewControllers: [UIViewController] = {
            return [self.newDayViewController("monday"),
                    self.newDayViewController("tuesday"),
                    self.newDayViewController("wednesday"),
                    self.newDayViewController("thursday"),
                    self.newDayViewController("friday"),
                    self.newDayViewController("saturday"),
                    self.newDayViewController("sunday")
            ]
        }()

        override func viewDidLoad() {
            super.viewDidLoad()

            dataSource = self
            delegate = self
            if let firstViewController = orderedViewControllers.first {
                self.navigationController!.navigationBar.topItem!.title = "monday"
                setViewControllers([firstViewController],
                                   direction: .Forward,
                                   animated: true,
                                   completion: nil)
            }
        }

        private func newDayViewController(day: String) -> UIViewController {
            return UIStoryboard(name: "Main", bundle: nil) .
                instantiateViewControllerWithIdentifier("\(day)")
        }

        func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
            if (!completed) {
                return
            }

            if let firstViewController = viewControllers?.first,
                let arrayIndex = orderedViewControllers.indexOf(firstViewController) {
                switch arrayIndex {
                case 0:
                    self.navigationController!.navigationBar.topItem!.title = "Monday"
                    break

                case 1:
                     self.navigationController!.navigationBar.topItem!.title = "Tuesday"
                    break

                case 2:
                     self.navigationController!.navigationBar.topItem!.title = "Wednesday"
                    break

                case 3:
                     self.navigationController!.navigationBar.topItem!.title = "Thursday"
                default:
                     self.navigationController!.navigationBar.topItem!.title = "Timetable"


                }
            }
        }
    }
    extension PageViewController: UIPageViewControllerDataSource {
        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 orderedViewControllers.last
            }
            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
            //MARK: - determine which viewController the user is o
            guard orderedViewControllersCount != nextIndex else {
                return orderedViewControllers.first
            }
            guard orderedViewControllersCount > nextIndex else {
                return nil
            }
            return orderedViewControllers[nextIndex]
        }
        func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
            return orderedViewControllers.count
        }
        func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
            guard let firstViewController = viewControllers?.first,
                firstViewControllerIndex = orderedViewControllers.indexOf(firstViewController) else {
                    return 0
            }
            return firstViewControllerIndex
        }
    }