Ok, so here's my issue:
I want to pass the value of a variable of type string through multiple view controllers and into one of the pages in my UIPageViewController. Here is the code for the UIPageViewController (starts with the import UIKit right below):
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var recieveProdTime2 = String() // 2nd view controller for productive time data to pass through
lazy var orderedViewControllers: [UIViewController] = {
return [self.newVC(viewController: "sbHome"), self.newVC(viewController: "sbPoints"), self.newVC(viewController: "sbShop")]
}()
var pageControl = UIPageControl()
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
self.delegate = self
configurePageControl()
if recieveProdTime2 != "" {
performSegue(withIdentifier: "segue3", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! HomeViewController
destinationVC.productive = recieveProdTime2
}
func configurePageControl() {
pageControl = UIPageControl(frame: CGRect(x: 0, y: UIScreen.main.bounds.maxY - 50, width: UIScreen.main.bounds.width, height: 50))
pageControl.numberOfPages = orderedViewControllers.count
pageControl.currentPage = 0
self.view.addSubview(pageControl)
}
func newVC(viewController: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
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 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
guard orderedViewControllers.count != nextIndex else {
return orderedViewControllers.first
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
let pageContentViewController = pageViewController.viewControllers![0]
self.pageControl.currentPage = orderedViewControllers.index(of: pageContentViewController)!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
As you can see, I am instantiating 3 different views. I want to pass the value of recieveProdTime2 into HomeViewController, which is one of the views in the UIPageViewController. Here is the code for HomeViewController:
import UIKit
class HomeViewController: UIViewController {
@IBOutlet weak var focusSession: UILabel!
@IBOutlet weak var breakSession: UILabel!
var productive = String() // Productive time data from ViewController.swift arrives and is store
override func viewDidLoad() {
super.viewDidLoad()
focusSession.text = productive
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I use the "prepare(for segue:...)" method in the PageViewController class and call on the variable named "productive" in the HomeViewController class to set the text of the label named "focusSession" in that class.
The Problem
Everything runs smoothly, there are no errors, and the project builds and runs....but the text of the label is empty!...It just appears as an empty label in the simulator! I check the error box, and I see this message: "Warning: Attempt to present Focus.HomeViewController on Focus.PageViewController whose view is not in the window hierarchy!"
How can I send data from the PageViewController to the HomeViewController and properly set the text of my label???
Try this:
replace your orderedViewControllers
initialization with:
lazy var orderedViewControllers: [UIViewController] = {
let sbPoint = self.newVC(viewController: "sbPoints") as! HomeViewController
if recieveProdTime2 != "" {
sbPoint.productive = recieveProdTime2
}
return [self.newVC(viewController: "sbHome"), sbPoint , self.newVC(viewController: "sbShop")]
}()
And enter some value in recieveProdTime2
.
Here you do not need to use prepareForSegue
so remove:
if recieveProdTime2 != "" {
performSegue(withIdentifier: "segue3", sender: self)
}
and
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! HomeViewController
destinationVC.productive = recieveProdTime2
}