iOS Swift - Change UIPageViewController page using UISegmentedControl - ios

I finnaly synchronized my segmentedController to the UIPageViewController in this way: when I swipe between pages, the segmented controller changes it's segment index. I want to know how to do the reverse too, when segmentedController's segment is tapped, to change the pageViewController page by segmentedController index. Here is my code:
class photoPageViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var segmentedControl: UISegmentedControl!
private var pageViewController: UIPageViewController?
var controllers = [thePageViewController]()
var thePage = thePageViewController()
override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControl()
}
private func createPageViewController() {
var pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as! UIPageViewController
pageController.dataSource = self
pageController.delegate = self
var firstController = getItemController(thePage.itemIndex)!
var startingViewControllers: NSArray = [firstController]
pageController.setViewControllers(startingViewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
pageViewController = pageController
addChildViewController(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController!.didMoveToParentViewController(self)
}
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
appearance.backgroundColor = UIColor.darkGrayColor()
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! thePageViewController
if itemController.itemIndex > 0 {
return getItemController(itemController.itemIndex-1)
}
return nil
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! thePageViewController
if itemController.itemIndex+1 < 3 {
return getItemController(itemController.itemIndex+1)
}
return nil
}
func getItemController(itemIndex: Int) -> UIViewController? {
var vc: thePageViewController? = nil
switch itemIndex {
case 0:
vc = self.storyboard!.instantiateViewControllerWithIdentifier("ViewController0") as! firstPhotoViewController
vc?.itemIndex = itemIndex
case 1:
vc = self.storyboard!.instantiateViewControllerWithIdentifier("ViewController1") as! secondPhotoViewController
vc?.itemIndex = itemIndex
case 2:
vc = self.storyboard!.instantiateViewControllerWithIdentifier("ViewController2") as! thirdPhotoViewController
vc?.itemIndex = itemIndex
default:
return nil
}
return vc
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return 3
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
func pageViewController(photoPageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers pageViewController: [AnyObject],
transitionCompleted completed: Bool)
{
if (!completed)
{
return;
}
segmentedControl.selectedSegmentIndex = thePageIndex
//thePageIndex is a global variable that changes when views from pageViewController appear
}
#IBAction func segmentedFunction(sender: AnyObject) {
switch segmentedControl.selectedSegmentIndex
{
case 0:
getItemController(0)
case 1:
getItemController(1)
case 2:
getItemController(2)
default:
println("...")
}
}}

I think you need to change your code a little bit! In my case I create several vc and put them to one array.
func createArrayOfControllers(){
newsLenta = self.storyboard?.instantiateViewControllerWithIdentifier("NewsLentaTableViewController") as NewsLentaTableViewController
mainPage = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageTableViewController") as MainPageTableViewController
onlinetranslation = self.storyboard?.instantiateViewControllerWithIdentifier("SingleTopicTableViewController") as SingleTopicTableViewController
tableViewControllers = [newsLenta, mainPage, onlinetranslation]
}
where tableViewController is global var var tableViewControllers = [UITableViewController]() ! I signed type TableViewController because all my vs's are type of table View controller. So the next function you need to change is
func viewControllerAtIndex(index : Int) -> UIViewController? {
if index > 2 || index < 0 {
return nil
}
return tableViewControllers[index]
}
In the end you just need to create action of segmentControl and reset your vc by index. Using this function:
func resetToMainPage(index: Int!) {
/* Getting the page View controller */
mainPageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageViewController") as UIPageViewController
self.mainPageViewController.dataSource = self
self.mainPageViewController.delegate = self
let pageContentViewController = self.viewControllerAtIndex(index)
segmentedControl.selectedSegmentIndex = index
self.mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
self.mainPageViewController.view.frame = CGRectMake(0, 95, self.view.frame.width, self.view.frame.height)
self.addChildViewController(mainPageViewController)
self.view.addSubview(mainPageViewController.view)
self.mainPageViewController.didMoveToParentViewController(self)
}
My question for your how do you update thePageIndex... I dont get that...

I found the way how to change UIPageViewController's content viewcontroller. I dont know is it right way or wrong but it works. Here is a code:
put this to viewdidload:
segmentControl.addTarget(self, action: "selectPageIndexBySegmentControl", forControlEvents: UIControlEvents.ValueChanged)
put it separte from viewdieload:
func selectPageIndexBySegmentControl(){
switch segmentControl.selectedIndex {
case 0:
println("zero index were selected")
pageContentViewController = self.viewControllerAtIndex(0)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
case 1:
println("first element were selected")
pageContentViewController = self.viewControllerAtIndex(1)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
case 2:
println("second element were selected")
pageContentViewController = self.viewControllerAtIndex(2)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
default:
break
}
}

Related

How to jump back to a first index of a page in UIPageviewController

I currently have a button that currently displays a UIPageViewController as an overlay on the homescreen. The user can always click on it and it would still display this ViewControllers embedded in a UIPageViewController. However at the moment, when the user clicks on the button to display the overlay and closes it and opens it again. The last page index / state of the last page is saved and displayed again. What i would like to do is to always display the first ViewController in the UIPageviewController. I have tried different ways but haven't had any luck.
Here is the screen capture that shows how the current mechanism works
https://gph.is/g/Z2QlyDa
HomeHelpViewController that contains the UIPageViewController
class HomeHelpViewController: UIPageViewController, UIPageViewControllerDataSource {
var helpPages: [UIViewController] = []
var currentIndex: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
let helpStoryboard = UIStoryboard(name: "HomeHelp", bundle: nil)
for scanIdentifier in ["homeHelpVC1","homeHelpVC2","homeHelpVC3","homeHelpVC4"] {
let scanVC = helpStoryboard.instantiateViewController(withIdentifier: scanIdentifier)
self.helpPages.append(scanVC)
}
self.dataSource = self
self.setViewControllers([self.helpPages.first!], direction: .forward, animated: true)
}
//MARK:- UIPageViewControllerDataSource
func pageViewController(_ pPageViewController: UIPageViewController, viewControllerBefore pViewController: UIViewController) -> UIViewController? {
self.currentIndex = self.helpPages.firstIndex(of: pViewController)!
if self.currentIndex > 0 {
return self.helpPages[self.currentIndex - 1]
}
return nil
}
func pageViewController(_ pPageViewController: UIPageViewController, viewControllerAfter pViewController: UIViewController) -> UIViewController? {
self.currentIndex = self.helpPages.firstIndex(of: pViewController)!
if self.currentIndex < (self.helpPages.count - 1) {
return self.helpPages[self.currentIndex + 1]
}
return nil
}
func presentationCount(for pPageViewController: UIPageViewController) -> Int {
return self.helpPages.count
}
func presentationIndex(for pPageViewController: UIPageViewController) -> Int {
return self.currentIndex
}
}
HomePageViewController that has the button display the UIPageViewController as an overlay
class HomePageViewController: UIViewController {
#IBOutlet weak var helpOverlay: BaseOverlayView!
#IBAction func helpButton(_ pSender: Any) {
self.helpButton.setImage(AppDelegate.helpButtonImage(tutorial: true), for: .normal)
self.helpOverlay.showOnView(self.view)
}
#IBAction func closeHelp(_ pSender: UIButton) {
self.helpOverlay.removeFromView()
self.helpButton.setImage(AppDelegate.helpButtonImage(tutorial: false), for: .normal)
}
}
declare a variable to access your HomeHelpViewController inside your HomePageViewController
class HomePageViewController: UIViewController {
weak var homePageController : HomeHelpViewController?
#IBOutlet weak var helpOverlay: BaseOverlayView!
#IBAction func helpButton(_ pSender: Any) {
if let homePageController = homePageController {
homePageController.setViewControllers([homePageController.helpPages.first!], direction: .forward, animated: true)
}
self.helpButton.setImage(AppDelegate.helpButtonImage(tutorial: true), for: .normal)
self.helpOverlay.showOnView(self.view)
}
#IBAction func closeHelp(_ pSender: UIButton) {
self.helpOverlay.removeFromView()
self.helpButton.setImage(AppDelegate.helpButtonImage(tutorial: false), for: .normal)
}
}
inside this loop assign your HomeHelpViewController
for scanIdentifier in ["homeHelpVC1","homeHelpVC2","homeHelpVC3","homeHelpVC4"] {
let scanVC = helpStoryboard.instantiateViewController(withIdentifier: scanIdentifier) as? HomePageViewController
scanVc?.homePageController = self
self.helpPages.append(scanVC)
}
This may be because the UIPageViewController was not properly dismissed.
func dismiss(animated flag: Bool, completion: (() -> Void)? = nil)
You can refer to the documentation here: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss
This effectively deallocates the UIPageViewController so that once the button is pressed, it will reinitialized again at the first page.

View doesn't show with "setViewController" in a UIPageViewController in Swift

I would like to change the pages showed by my UIPageView programatically.
I created two ViewController that are intended to be displayed in the PageView, and I set the initial View with "setViewControllers" in my viewDidLoad. I works, the view is displayed and I can swipe on the screen to switch between the two views.
My problem being that when I try to call again "setViewControllers" to change the displayed view when I click a button, nothing happens.
I'm using delegates since the buttons are part of another ViewController, and used NSLog to make sure the functions were called, which is the case.
If anyone could help me understand why the "setViewControllers" method doesn't do anything, that would be great.
Here is my code for my UIPageViewController:
import UIKit
class FrontContentController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, sideMenuDelegate {
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return subViewControllers.count
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex:Int = subViewControllers.index(of: viewController) ?? 0
if currentIndex <= 0 {
return nil
}
return subViewControllers[currentIndex - 1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex:Int = subViewControllers.index(of: viewController) ?? 0
if currentIndex >= subViewControllers.count - 1 {
return nil
}
return subViewControllers[currentIndex + 1]
}
lazy var subViewControllers:[UIViewController] = {
return [
UIStoryboard(name: "frontPage", bundle: nil).instantiateViewController(withIdentifier: "FirstContent") as! FirstContentController,
UIStoryboard(name: "frontPage", bundle: nil).instantiateViewController(withIdentifier: "SecondContent") as! SecondContentController
]
}()
var sideMenuVC : SideMenuController!
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
self.sideMenuVC = (self.storyboard?.instantiateViewController(withIdentifier: "SideMenu") as! SideMenuController)
self.setViewControllers([subViewControllers[0]], direction: .forward, animated: true, completion: nil)
// Do any additional setup after loading the view.
}
func changeColor(_ color: UIColor) {
if color == .blue {
self.setViewControllers([subViewControllers[0]], direction: .forward, animated: false, completion: nil)
NSLog("Blue Delegate")
}
if color == .red {
self.setViewControllers([subViewControllers[1]], direction: .forward, animated: false, completion: nil)
NSLog("Red Delegate")
}
}
}
And in case it's relevant, the separate UIViewController with the buttons (a side menu) :
import UIKit
protocol sideMenuDelegate: AnyObject {
func changeColor(_ color : UIColor)
}
class SideMenuController: UIViewController {
weak var delegate : sideMenuDelegate?
var frontPageVC : FrontPageController!
var frontContentPC : FrontContentController!
override func viewDidLoad() {
super.viewDidLoad()
let storyboard = UIStoryboard(name: "frontPage", bundle: nil)
frontPageVC = (storyboard.instantiateViewController(withIdentifier: "FrontPage") as! FrontPageController)
frontContentPC = (storyboard.instantiateViewController(withIdentifier: "FrontContent") as! FrontContentController)
self.delegate = frontContentPC
self.view.backgroundColor = UIColor.black
}
#IBAction func pressBlueButton(_ sender: Any) {
delegate?.changeColor(UIColor .blue)
}
#IBAction func pressRedButton(_ sender: Any) {
delegate?.changeColor(UIColor .red)
}
}
Thanks

UIPageViewController setViewControllers

I am trying to implement a PageViewController that switches to a different ViewController when a button is pressed. I can successfully load each "child" ViewController using the setViewControllers method during viewDidLoad().
However when I call the setViewControllers method outside viewDidLoad(), it does not change the current "child" ViewController.
Can you call the method setViewControllers at any point or just once during viewDidLoad()? Also is there a way to change a variable in the pageviewcontrollers dataSource extensions?
My project consists of a entry ViewController with a "Settings" button and a ContainerView. Inside the ContainerView I have the UIPageViewController.
Code for PageViewController:
import UIKit
class PageViewController: UIPageViewController {
var slides = [SlideItem]()
var currentIndex: Int!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
initSlides()
}
override func viewDidLoad() {
super.viewDidLoad()
if let viewController = viewSlideViewController(currentIndex ?? 0){
let viewControllers = [viewController]
setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
}
dataSource = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewSlideViewController(_ index: Int) -> SlideViewController? {
guard let storyboard = storyboard,
let page = storyboard.instantiateViewController(withIdentifier: "SlideViewController") as? SlideViewController else {
return nil
}
page.slide = slides[index]
page.slideIndex = index
return page
}
func viewSettingsViewController(_ index: Int) -> SettingsViewController? {
guard let storyboard = storyboard,
let page = storyboard.instantiateViewController(withIdentifier: "SettingsViewController") as? SettingsViewController else {
return nil
}
return page
}
func initSlides(){
slides.append(SlideItem.init(filename: "Slide 1", comparison: false, highYield: false, videoURL: nil,
groupOrganSystem: ["A"],
groupMedicalSpecialty: ["B"]))
slides.append(SlideItem.init(filename: "Slide 2", comparison: false, highYield: false, videoURL: nil,
groupOrganSystem: ["A"],
groupMedicalSpecialty: ["B"]))
}
func sidebarCommands(button: String, state: Bool){
switch button {
case "settings":
self.setViewControllers([viewSettingsViewController(0)!], direction: .forward, animated: false, completion: nil)
print("settings")
default:
return
}
}
}
Extensions:
extension PageViewController : UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let viewController = viewController as? SlideViewController,
let index = viewController.slideIndex,
index > 0 {
return viewSlideViewController(index - 1)
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let viewController = viewController as? SlideViewController,
let index = viewController.slideIndex,
(index + 1) < slides.count {
return viewSlideViewController(index + 1)
}
return nil
}
}
You can use UIPageviewController in this way: (inheritance)
https://medium.com/how-to-swift/how-to-create-a-uipageviewcontroller-a948047fb6af
You can call setViewControllers at any point (I've been doing that).
The fact that it does not produce expected results is probably a result of bug in your code, include your code if you want to help out with that.
Thank you for your help, I figured out what I was doing wrong. I didn't have the right reference for the active PageViewController in the ContainerView.
So of course called the setViewControllers function on random PageViewController did not produce the correct results.
I found this answer explains how to correctly get a reference from a ContainerView

UIPageViewController bad access error

I know the error means I have a NULL pointer, but I am unsure as to WHY that is, and I assume it must be something I did wrong in my code. My index starts at 1 because I want it to start in the middle view controller which is the home page. I am trying to make a page view controller to swipe between view controllers similar to snapchat. I have the following code:
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var viewControllersArray = [UIViewController]()
var pageIndex: Int?
let selectedIndex = 1
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clearColor()
let vc1 = storyboard?.instantiateViewControllerWithIdentifier("ProfileView") as! ProfileViewController
let vc2 = storyboard?.instantiateViewControllerWithIdentifier("HomeView") as! HomeViewController
let vc3 = storyboard?.instantiateViewControllerWithIdentifier("MatchesView") as! MatchViewController
viewControllersArray.append(vc1)
viewControllersArray.append(vc2)
viewControllersArray.append(vc3)
self.dataSource = self
let pageContentViewController = self.viewControllerAtIndex(selectedIndex)
self.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil) //Error here
}
the error occurs at this line:
self.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil) //Error here
The error is as follows: "Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff58d57ff8)
Here is my viewControllerAtIndex function:
func viewControllerAtIndex(index : Int) -> UIViewController? {
if((self.viewControllersArray.count == 0) || (index >= self.viewControllersArray.count)) {
return nil
}
let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! PageViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
Here is my storyboard with the view controllers to swipe between:
Any and all help is greatly appreciated!
It looks like
func viewControllerAtIndex(index : Int) -> UIViewController? {
if((self.viewControllersArray.count == 0) || (index >= self.viewControllersArray.count)) {
return nil
}
let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! PageViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
Needs to be:
func viewControllerAtIndex(index : Int) -> UIViewController? {
if((self.viewControllersArray.count == 0) || (index >= self.viewControllersArray.count)) {
return nil
}
return viewControllersArray[index]
}
Additionally
let selectedIndex = 1
should be
let selectedIndex = 0
since 1 will refer to the second page.

Change index of VC in page view controller (Swift)

Using the following code, I have a series of view controllers embedded in a page view controller that I'm swiping through. I just can't find a way to segue to another view controller via a bar button press. I'm planning on writing a separate function for each bar button icon in each view controller.
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
private var pages: [UIViewController]!
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
self.pages = [
self.storyboard!.instantiateViewControllerWithIdentifier("FirstNav") as! UINavigationController,
self.storyboard!.instantiateViewControllerWithIdentifier("SecondNav") as! UINavigationController,
self.storyboard!.instantiateViewControllerWithIdentifier("ThirdNav") as! UINavigationController,
self.storyboard!.instantiateViewControllerWithIdentifier("FourthNav") as! UINavigationController
]
let startingViewController = self.pages.first! as UIViewController
self.setViewControllers([startingViewController], direction: .Forward, animated: false, completion: nil)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let index = (self.pages as NSArray).indexOfObject(viewController)
// if currently displaying last view controller, return nil to indicate that there is no next view controller
return (index == self.pages.count - 1 ? nil : self.pages[index + 1])
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let index = (self.pages as NSArray).indexOfObject(viewController)
// if currently displaying first view controller, return nil to indicate that there is no previous view controller
return (index == 0 ? nil : self.pages[index - 1])
}
}
Change your implementation of PageViewController to the following (I made some changes in the methods you already implemented, and I added a new instance method.)
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
private var pages: [UINavigationController]!
private var currentPageIndex: Int!
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
self.pages = [
self.storyboard!.instantiateViewControllerWithIdentifier("FirstNav") as! UINavigationController,
self.storyboard!.instantiateViewControllerWithIdentifier("SecondNav") as! UINavigationController,
self.storyboard!.instantiateViewControllerWithIdentifier("ThirdNav") as! UINavigationController,
self.storyboard!.instantiateViewControllerWithIdentifier("FourthNav") as! UINavigationController
]
(self.pages[0].topViewController as! FirstViewController).parentPageViewController = self
(self.pages[1].topViewController as! SecondViewController).parentPageViewController = self
(self.pages[2].topViewController as! ThirdViewController).parentPageViewController = self
(self.pages[3].topViewController as! FourthViewController).parentPageViewController = self
self.currentPageIndex = 0
let startingViewController = self.pages.first! as UINavigationController
self.setViewControllers([startingViewController], direction: .Forward, animated: false, completion: nil)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let index = (self.pages as NSArray).indexOfObject(viewController)
self.currentPageIndex = index
// if currently displaying last view controller, return nil to indicate that there is no next view controller
return (self.currentPageIndex == self.pages.count - 1 ? nil : self.pages[self.currentPageIndex + 1])
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let index = (self.pages as NSArray).indexOfObject(viewController)
self.currentPageIndex = index
// if currently displaying first view controller, return nil to indicate that there is no previous view controller
return (index == 0 ? nil : self.pages[index - 1])
}
func displayPageForIndex(index: Int, animated: Bool = true) {
assert(index >= 0 && index < self.pages.count, "Error: Attempting to display a page for an out of bounds index")
// nop if index == self.currentPageIndex
if self.currentPageIndex == index { return }
if index < self.currentPageIndex {
self.setViewControllers([self.pages[index]], direction: .Reverse, animated: true, completion: nil)
} else if index > self.currentPageIndex {
self.setViewControllers([self.pages[index]], direction: .Forward, animated: true, completion: nil)
}
self.currentPageIndex = index
}
}
Now, in each of your child view controllers, add two pieces of code:
A property that maintains a weak reference to the parent PageViewController instance.
weak var parentPageViewController: PageViewController!
An IBAction to which you connect each of your bar button items. You may need to change the body of this method depending on how your Storyboard is set up.
#IBAction func barButtonTapped(sender: UIBarButtonItem) {
var newIndex = -1
switch sender.title! {
case "First":
newIndex = 0
case "Second":
newIndex = 1
case "Third":
newIndex = 2
case "Fourth":
newIndex = 3
default: break
}
self.parentPageViewController.displayPageForIndex(newIndex)
}
Does each controller need to be embedded in a UINavigationController? You could just have a UINavigationController embed a single UIViewController, that view controller references a pageviewcontroller and a barButtonItem, when the barButtonItem is tapped trigger an action that tells the pageviewcontroller to change indexes.
Or if you want to go with your current plan of action which is a barButtonItem in each UINavigationController, write a protocol with a delegate method didSelectBarButtonAtIndex or something, then give each UINavigationController a delegate property, have the pageviewcontroller conform to the protocol and become the delegate for each nav controller. Then when a bar button is tapped, call the delegate method, which should make the page controller change it's index.

Resources