I essentially have a a root ViewController that I want passed onto the collection of ViewControllers (all different classes themselves) connected through the PageViewController.
Currently, I set up a prepareforsegue in the root ViewController passing data. I then declared the variable in the PageViewController and trying to figure how to pass the data onto the ViewControllers.
I'm currently just doing a simple Hello World test, so my code is a bit simple. Here is my RootViewController which I have passing onto the PageViewController (and hence onto the subsequent VC's connected to the PageViewController):
class RootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var hello: String! = "Hello World!"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "testSegue"){
var svc = segue.destinationViewController as! PageViewController;
svc.datapassed = self.hello
}
}
My PageView Controller is a bit more complicated. I'm using the storyboard ID method, since I want the pageviewcontroller to display view controllers of different classes as opposed to the multitude of tutorials which show one view controller template and different image contents...
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var datapassed: String!
var index = 0
var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
override func viewDidLoad() {
super.viewDidLoad()
setupPageControl()
self.dataSource = self
self.delegate = self
let startingViewController = self.viewControllerAtIndex(self.index)
let viewControllers: NSArray = [startingViewController]
self.setViewControllers(viewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
// Do any additional setup after loading the view.
}
func viewControllerAtIndex(index: Int) -> UIViewController! {
if index == 0 {
return self.storyboard!.instantiateViewControllerWithIdentifier("FirstNavigationController") as! UIViewController
}
if index == 1 {
return self.storyboard!.instantiateViewControllerWithIdentifier("SecondNavigationController") as! UIViewController
}
return nil
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {
let identifier = viewController.restorationIdentifier
let index = self.identifiers.indexOfObject(identifier!)
if index == identifiers.count - 1 {
return nil
}
self.index = self.index + 1
return self.viewControllerAtIndex(self.index)
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
let identifier = viewController.restorationIdentifier
let index = self.identifiers.indexOfObject(identifier!)
if index == 0 {
return nil
}
self.index = self.index - 1
return self.viewControllerAtIndex(self.index)
}
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
}
func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
return self.identifiers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
return 0
}
}
Lastly, I simply want the first ViewController connected to the pageviewcontroller to display the text from the variable passed, datapassed.
class FirstViewController: UIViewController {
@IBOutlet weak var helloLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
helloLabel.text = datapassed
// Do any additional setup after loading the view.
}
}
EDIT: Possible Solution and Final Code:
class RootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var carinfos: String! = "Hello World"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let svc = segue.destinationViewController as? PageViewController
where segue.identifier == "testSegue" {
svc.dataPassed = self.carinfos
}
}
}
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var dataPassed: String? {
didSet {
self.updateCurrentViewController()
}
}
var index = 0
var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
let startingViewController = self.viewControllerAtIndex(self.index)
let viewControllers: NSArray = [startingViewController]
self.setViewControllers(viewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
func updateCurrentViewController() {
if let firstViewController = self.viewControllerAtIndex(self.index) as? FirstViewController, let data = self.dataPassed {
firstViewController.dataPassed = data
}
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {
let identifier = viewController.restorationIdentifier
let index = self.identifiers.indexOfObject(identifier!)
if index == identifiers.count - 1 {
return nil
}
self.index = self.index + 1
return self.viewControllerAtIndex(self.index)
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
let identifier = viewController.restorationIdentifier
let index = self.identifiers.indexOfObject(identifier!)
if index == 0 {
return nil
}
self.index = self.index - 1
let viewController = self.viewControllerAtIndex(self.index)
self.updateCurrentViewController()
return viewController
}
func viewControllerAtIndex(index: Int) -> UIViewController! {
if index == 0 {
return self.storyboard!.instantiateViewControllerWithIdentifier("FirstNavigationController") as! UIViewController
}
if index == 1 {
return self.storyboard!.instantiateViewControllerWithIdentifier("SecondNavigationController") as! UIViewController
}
return nil
}
func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
return self.identifiers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
return 0
}
}
class FirstViewController: UIViewController {
var dataPassed: String?
@IBOutlet weak var firstLabelTest: UILabel!
@IBOutlet weak var firstLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
println(dataPassed)
firstLabel.text = "Hello, this is First"
self.populateData()
}
func populateData() {
if let data = self.dataPassed {
self.firstLabelTest.text = self.dataPassed
}
}
}
You can simply pass it through the view controller structure to get this working, although that's not much of a thoughtful design. To do that, first, make sure you are properly casting the
destinationViewController
using anif let
binding and a conditional downcast (as?
). You can also combine the comparison to the segue'sidentifier
using awhere
clause. Then, you'll have the object on which to set your data.In
FirstViewController
, use a property observer to update the label when yourdataPassed
variable it set, and also update it onviewDidLoad
.Also, your
hello
property should not be an implicitly unwrapped type, so you can remove the!
from the declaration.