1

I've been hitting my head on this for couple of days. My goal is to create an app that has a container view connected to a UIPageViewController such that I can display pages of different data/views. (my existing app w/ UITabBarController w/ 1 single data page/view works)

enter image description here

So far, I've created the containerView and the UIPageController and the different ViewControllers using the guidance from this https://stackoverflow.com/a/26024779/14414215 and going thru a lot of SO pages but unable to get to the result I want.

In the Root VC (Train) I have this:

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    print("VCTrain segue ID:\(String(describing: segue.identifier))\n")
    if (segue.identifier == "segueTrainContainerViewPages") {
      print("prepare for segueTrainContainerViewPages")
      let vcContainerView = segue.destination as! VCTrainContainerViewPages
      vcContainerView.myLabel = "HELLO"        // This gets Passed
      
      // workoutTitle is obtained from the LIBRARY tab once the user clicks 
      // on a row in the tableview. It is blank until user selects a workout Title
      vcContainerView.myLabel1 = workoutTitle  // This remains Blank
    }
  }

This is the VCTrainContainerViewPages which is basically a copy/paste of https://stackoverflow.com/a/26024779/14414215

import UIKit

class VCTrainContainerViewPages: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
  
  var pages = [UIViewController]()
  var myLabel = String()
  var myLabel1 = String()

  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.delegate = self
    self.dataSource = self
    
    let page1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "id1")
    let page2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "id2")
    let page3: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "id3")
    
    pages.append(page1)
    pages.append(page2)
    pages.append(page3)
    
    setViewControllers([page1], direction: UIPageViewController.NavigationDirection.forward, animated: false, completion: nil)
    
    print("\nVCTrainContainerViewPages VDL myLabel :\(myLabel)")
    print("VCTrainContainerViewPages VDL myLabel1:\(myLabel1)\n")
  }
  
  override func viewDidAppear(_ animated: Bool) {
    
  }
   
  
  func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController)-> UIViewController? {
    
    let cur = pages.firstIndex(of: viewController)!
    
    var prev = (cur - 1) % pages.count
    if prev < 0 {
      prev = pages.count - 1
    }
    return pages[prev]
  }
  
  func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController)-> UIViewController? {
    
    let cur = pages.firstIndex(of: viewController)!
    
    let nxt = abs((cur + 1) % pages.count)
    return pages[nxt]
  }
  
  func presentationIndex(for pageViewController: UIPageViewController)-> Int {
    return pages.count
  }
}

Currently what works:

  1. The UIPageViewController works (swiping works and all the 3 view controllers moves)
  2. MyLabel gets passed from MainVC to UIPageViewController (Train Container View Pages)

What I need to work

  1. workout Title from the Library Tab. This gets passed from the Library Tab (once user selects a workout) to the Train Tab and then gets passed to Train Container View Pages

The prepare for Segue function in Root VC (Train) only gets called 1x during the initial load of the TRAIN page. Subsequent load of this page doesn't call prepareForSegue ever again.

In the working scenario (w/o the container view / UIPageController), I was using ViewDidAppear to receive the data passed from the LIBRARY Tab. Is it possible to use ViewDidAppear to pass the data?

app4g
  • 670
  • 4
  • 24
  • Could you show the code where "workoutTitle is obtained from the LIBRARY tab once the user clicks on a row in the tableview. It is blank until user selects a workout Title" – claude31 Dec 29 '20 at 15:02
  • Prepare is called only when you trigger the segue. I understand that this is the first time you hit the "train". – claude31 Dec 29 '20 at 15:09
  • @claude31 Code for "WorkoutTitle from LIBRARY Tab " https://stackoverflow.com/a/65499693/14414215 Almost all the tutorials I read / SO pages uses prepare for segue as a way to pass data, hence that's what I tried. Thanks for the help – app4g Dec 29 '20 at 22:39

0 Answers0