Reputation: 61
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
}
}
}
Upvotes: 2
Views: 2028
Reputation: 1840
In swift3
you can do like
In Main view where you embeded an pageviewcontroller you can use segue with identifier
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier=="challengepostssegue"{
let destination=segue.destination as! PageMainController
destination.challengeId=challengId
}
}
In PageMainController declare one variable optional type
var challengeId:String?
Upvotes: 0
Reputation: 2782
Depending on the needs and other structure of your app, you could also use the responder chain to provide data to any view controllers in your hierarchy.
Then it's a simple as this:
class FirstViewController : UIViewController {
@IBOutlet weak var helloLabel: UILabel!
var dataPassed: String? {
didSet {
if let data = self.dataPassed {
self.helloLabel.text = data
}
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let dataSource = self.nextResponder()?.targetForAction( "hello", withSender: self ) as? RootViewController {
self.dataPassed = dataSource.hello
}
}
}
class RootViewController : UIViewController {
var hello: String = "Hello World!"
}
Upvotes: 0
Reputation: 2782
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 an if let
binding and a conditional downcast (as?
). You can also combine the comparison to the segue's identifier
using a where
clause. Then, you'll have the object on which to set your data.
In FirstViewController
, use a property observer to update the label when your dataPassed
variable it set, and also update it on viewDidLoad
.
Also, your hello
property should not be an implicitly unwrapped type, so you can remove the !
from the declaration.
class FirstViewController : UIViewController {
@IBOutlet weak var helloLabel: UILabel!
var dataPassed: String?
override func viewDidLoad() {
super.viewDidLoad()
self.populateData()
}
func populateData() {
if let data = self.dataPassed {
self.helloLabel.text = self.dataPassed
}
}
}
class PageViewController : UIPageViewController {
var index = 0
var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
var dataPassed: String? {
didSet {
self.updateCurrentViewController()
}
}
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 updateCurrentViewController() {
if let firstViewController = self.viewControllerAtIndex(self.index) as? FirstViewController, let data = self.dataPassed {
firstViewController.dataPassed = data
}
}
func viewControllerAtIndex(index: Int) -> UIViewController! {
// Create your VC as in the project template
return nil
}
}
class RootViewController : UIViewController {
var hello: String = "Hello World!"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
super.prepareForSegue( segue, sender: sender )
if let svc = segue.destinationViewController as? PageViewController
where segue.identifier == "testSegue" {
svc.dataPassed = self.hello
}
}
}
Upvotes: 1