Search code examples
iosswifttabbarcontroller

Issues with StoryBoard ViewControllers in a Tabbed IOS App


In the struggle of developing a Tabbed IOS App with Swift 1.2 and Xcode 6.3 based on MVC, I'm using the visual Storyboard elements instead of to do it programatically because I'm not an experienced developer. In the image attached below you can see the Architecture in the StoryBoard of the App:

StoryBoard Architecture

The App consists in:

  • One TabBarController with four TabBar Items.
  • Each Item has its own ViewController in Storyboard.
  • All of them are linked with the relationship seque(ViewControllers) in StoryBoard.
  • Each ViewController in the StoryBoard has its own Class.
  • The last Item has an embedded NavigationController because I'm using a PageMenu project https://github.com/uacaps/PageMenu to include a paging menu controller with a two child ViewControllers

The Issues I'm having until this point are:

  1. The two child ViewControllers are not linked with the Last TabBar Item in the StoryBoard,as you can see in the figure above, only are instantiated in the parent ViewController Class(PageMenuViewController1), normally this PageMenu works but sometimes the last TabBar Item dissapears, I'm very confused with this issue.
  2. The override func viewWillAppear into the default child ViewController is called twice at the first time, I've include a println("ClubsController viewWillAppear").

The code of the ViewControllers is

import UIKit


class ClubsViewController: UIViewController, UITableViewDataSource{

  @IBOutlet var tableview:UITableView!

  let apiClient = ApiClient()

  var clubs: [Club]!

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    println("ClubsController viewWillAppear")

    apiClient.clubsService.getList() { clubs, error in
      if clubs != nil {
        self.clubs = clubs
        self.tableview?.reloadData()
      }
      else {
        println("error: \(error)")
      }
    }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.clubs?.count ?? 0
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell {
    var cell = tableView.dequeueReusableCellWithIdentifier("clubObjectCell") as! ClubTableViewCell
    cell.clubObject = self.clubs?[indexPath.row]
    return cell
  }

}

The code of the PageMenuViewController is

import UIKit

class PageMenuViewController1: UIViewController {

  var pageMenu : CAPSPageMenu?

  override func viewDidAppear(animated: Bool) {

    println("PageMenuViewController1 viewWillAppear")

    super.viewDidAppear(animated)
    // Array to keep track of controllers in page menu
    var controllerArray : [UIViewController] = []

    // Create variables for all view controllers you want to put in the
    // page menu, initialize them, and add each to the controller array.
    // (Can be any UIViewController subclass)
    // Make sure the title property of all view controllers is set
    // Example:
    var controller1 = storyboard!.instantiateViewControllerWithIdentifier("ClubsViewController")! as! ClubsViewController
    controller1.title = "CLUBS"
    controllerArray.append(controller1)
    var controller2 = storyboard!.instantiateViewControllerWithIdentifier("PartiesViewController")! as! PartiesViewController
    controller2.title = "PARTIES"
    controllerArray.append(controller2)

    // Customize page menu to your liking (optional) or use default settings by sending nil for 'options' in the init
    // Example:
    var parameters: [CAPSPageMenuOption] = [
      .MenuItemSeparatorWidth(4.3),
      .UseMenuLikeSegmentedControl(true),
      .MenuItemSeparatorPercentageHeight(0.1)
    ]

    // Initialize page menu with controller array, frame, and optional parameters
    pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRectMake(0.0, 0.0, self.view.frame.width, self.view.frame.height), pageMenuOptions: parameters)

    // Lastly add page menu as subview of base view controller view
    // or use pageMenu controller in you view hierachy as desired
    self.view.addSubview(pageMenu!.view)
  }
}

Appreciate help to accomplish the best practices until this point.


Solution

  • I've not familiar with the CAPSPageMenu but there is nothing wrong with having scenes in a storyboard that aren't connected with a segue - this is just a convenience to help with transitions, and instantiating them with instantiateViewControllerWithIdentifier is totally legitimate.

    Something that does stand out looking at your storyboard is the way your table view controller with the navigation view controller is wired up.

    The navigation viewcontroller should have the relationship with the tab bar controller - not the table viewcontroller.

    Here's a screenshot of how the connection should look. Possibly this is why you're sometimes loosing a tab.

    Storyboard layout for tabs with a navigation controller