1

I followed a tutorial on how to implement a custom tab pager in a navigation controller. My setup looks like this. On the BuyStatsTapPager (on the right) you should see that you can switch between "buy" and "contest".

enter image description here

This basically works by instantiating view controllers depending on which child tab is clicked. The problem is that I also have data in this class (I have successfully set 'var selectedPlayerBuyStats' from the previous view controller prepare for segue method) that I need to pass to the instantiated controllers.

Down at the bottom in 'updateView()'I thought I had a way figured out because I'm able to access the child view controllers tableview to set its size and dimension. I have the lines commented out that aren't working. The IDE is successfully finding the property off of the child view controllers that I need to set, but when I actually try to get the data in the child view controller its nil. Is there another way I could maybe try to do this? Thanks

import UIKit



class BuyStatsTabPager: BuyStats{


@IBOutlet var segmentedControl: UISegmentedControl!
@IBOutlet weak var scoreKey: UIBarButtonItem!
@IBOutlet weak var standings: UIBarButtonItem!

var selectedPlayerBuyStats: Player! = nil

override func viewDidLoad() {

    navigationController?.navigationBar.barTintColor = UIColor(red: 27/255, green: 27/255, blue: 27/255, alpha: 1)

    scoreKey.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Helvetica", size: 13.0)!], for: UIControlState.normal)
    scoreKey.tintColor = UIColor.blue

    standings.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Helvetica", size: 13.0)!], for: UIControlState.normal)
    standings.tintColor = UIColor.blue


    setupView()
}

private func setupView() {
    setupSegmentedControl()
    updateView()
}

private func setupSegmentedControl() {
    // Configure Segmented Control
    segmentedControl.removeAllSegments()
    segmentedControl.insertSegment(withTitle: "Buy", at: 0, animated: false)
    segmentedControl.insertSegment(withTitle: "Score", at: 1, animated: false)
    segmentedControl.addTarget(self, action: #selector(selectionDidChange(_:)), for: .valueChanged)
    segmentedControl.selectedSegmentIndex = 0
}

func selectionDidChange(_ sender: UISegmentedControl) {
    updateView()
}


private lazy var viewContestTab: BuyStatsTab = {
    // Load Storyboard
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

    // Instantiate View Controller
    var viewController = storyboard.instantiateViewController(withIdentifier: "BuyStatsTab") as! BuyStatsTab


    // Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

private lazy var viewRoundTab: BuyStatsContestTab = {
    // Load Storyboard
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

    // Instantiate View Controller
    var viewController = storyboard.instantiateViewController(withIdentifier: "BuyStatsContestTab") as! BuyStatsContestTab




    // Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

private func add(asChildViewController viewController: UIViewController) {
    // Add Child View Controller
    addChildViewController(viewController)

    // Add Child View as Subview
    view.addSubview(viewController.view)

    // Configure Child View
    viewController.view.frame = view.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    // Notify Child View Controller
    viewController.didMove(toParentViewController: self)
}

private func remove(asChildViewController viewController: UIViewController) {
    // Notify Child View Controller
    viewController.willMove(toParentViewController: nil)

    // Remove Child View From Superview
    viewController.view.removeFromSuperview()

    // Notify Child View Controller
    viewController.removeFromParentViewController()
}

private func updateView() {
    if segmentedControl.selectedSegmentIndex == 0 {

        //this is working so I have the data I need to pass
        print(selectedPlayerBuyStats.p)

        let position = viewRoundTab.tableView.contentOffset.y;
        viewContestTab.tableView.contentOffset = CGPoint(x:0, y:position);

        //but it isn't working this way
        //viewContestTab.selectedPlayer = selectedPlayerBuyStats


        remove(asChildViewController: viewRoundTab)
        add(asChildViewController: viewContestTab)
    } else {


        print(selectedPlayerBuyStats.Name)

        let position = viewContestTab.tableView.contentOffset.y;
        viewRoundTab.tableView.contentOffset = CGPoint(x:0, y:position);

        //viewRoundTab.selectedPlayer = selectedPlayerBuyStats

        remove(asChildViewController: viewContestTab)
        add(asChildViewController: viewRoundTab)
    }
}


}

EDIT:

So I'm trying to use prepare for segue in the tab pager class but still having problems. 1. I don't know how to check which child class the data should go to. 2. Even if I just send like this to the first child class the data is still nil on the other side.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {


        let buyStats = segue.destination as! BuyStatsTab

        buyStats.selectedPlayer = selectedPlayer


}

Here is the first of the recipient child view controllers.

class BuyStatsTab: UIViewController, UITableViewDelegate, UITableViewDataSource{

@IBOutlet var tableView: UITableView!

let cellReuseIdentifier = "cell"

var stats = [BuyStat]()

var selectedPlayer: Player! = nil


override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
    self.tableView.rowHeight = 70.0
    self.tableView.tableFooterView = UIView()
    tableView.delegate = self
    tableView.dataSource = self


    stats = [
             BuyStat(purchaseAmount: 0.0, category: "Pts", average: selectedPlayer.p, price: "$75"),
             BuyStat(purchaseAmount: 0.0, category: "Reb", average: 6.5, price: "$175"),
             BuyStat(purchaseAmount: 0.0, category: "Ast", average: 6.7, price: "$200"),
             BuyStat(purchaseAmount: 0.0, category: "Stl", average: 2.2, price: "$300"),
             BuyStat(purchaseAmount: 0.0, category: "Blk", average: 0.4, price: "$325"),
             BuyStat(purchaseAmount: 0.0, category: "3pt", average: 3.3, price: "$325"),
             BuyStat(purchaseAmount: 0.0, category: "TO", average: 2.4, price: "$350")]

    tableView.reloadData()

}

selectedPlayer.p in the array should have data.

Louis Sankey
  • 481
  • 8
  • 26
  • You need to pass the data via prepare for segue just like you did it to get `var selectedPlayerBuyStats` value passed. – MwcsMac Apr 10 '17 at 15:56
  • Thanks for the reply. I will try but I'm still a little confused because I don't have a segue identifier. – Louis Sankey Apr 10 '17 at 16:04
  • Try making the viewContestTab variable not lazy – Timmy Apr 10 '17 at 16:46
  • Have a look at this and see if it helps. http://stackoverflow.com/questions/31440378/swift-accessing-and-updating-tableview-in-container-view – MwcsMac Apr 10 '17 at 19:47
  • @ Timmy, thank for the reply. Seems like it could have to do with the child view controllers being lazy, but when I remove that I get an error under 'self.add(asChildViewController: viewController)'. I get 'Value of type NSObject -> () -> BuyStatsTapPager has no member add'. I'll keep trying things. – Louis Sankey Apr 10 '17 at 21:30

1 Answers1

0

Based on the comments I was able to get to the exact answer. I just had to set the data inside of the lazy variable viewContestTab instead of down further in the updateView(). I thought doing it in updateView() would work because the tutorial had me access the tableview from there. I'm still not sure why I can access the tableview in updateView() but not set the other data. If anyone thinks this deserves a better explanation I'll gladly give them best answer.

 private lazy var viewRoundTab: BuyStatsContestTab = {

    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

    var viewController = storyboard.instantiateViewController(withIdentifier: "BuyStatsContestTab") as! BuyStatsContestTab

    viewController.selectedPlayer = self.selectedPlayerBuyStats

    self.add(asChildViewController: viewController)

    return viewController
}()
Louis Sankey
  • 481
  • 8
  • 26