2

I added 2 tabBar items from storyboard and one UITabBarItem - Menu programmatically. I am successfully able to open the controllers corresponding to tabBarItems which I created using storyboard. However, when I click on "Menu" a blank black screen appears,

@objc public class MainScreenTabsController : UITabBarController {
public override func viewDidLoad() {
    super.viewDidLoad()
    let tabController = MyViewController()
    let tabBarItem = UITabBarItem(title: "Menu", image: UIImage(named: "more-options.png"), selectedImage: UIImage(named: "more-options"))
    tabController.tabBarItem = tabBarItem
    var array = self.viewControllers
    array?.append(tabController)
    self.viewControllers = array
}

public func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    return true;
}

public override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
}
}

I followed couple of tutorials for adding tab bar item but all of them had the code I wrote. Am I missing out something very basic? The three dots represent menu. The word menu is not included because in the real code I gave a blank string

EDIT:

Class for Menu Controller

@objc public class MyViewController:UIViewController {

public override func viewDidLoad() {
    super.viewDidLoad()
}

public override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
}
}
A_G
  • 2,260
  • 3
  • 23
  • 56

2 Answers2

4

Your app is doing exactly what your code is telling it to do. You are creating an instance of MyViewController and adding it to the UITabBarController's array of View Controllers.

Your MyViewController class file simply defines a blank, black view.

I'm guessing you created a ViewController in your Storyboard that you want to use as MyViewController? If so, you need to instantiate that from the storyboard.

When you're editing your storyboard, assign the MyViewController class to the VC you want to use, and also give it a Storyboard ID - such as MyVC. Then, edit your viewDidLoad function to this:

public override func viewDidLoad() {
    super.viewDidLoad()

    // wrong way
    //  let tabController = MyViewController()

    if let tabController = storyboard?.instantiateViewController(withIdentifier: "MyVC") as? MyViewController {

        let tabBarItem = UITabBarItem(title: "Menu", image: UIImage(named: "more-options.png"), selectedImage: UIImage(named: "more-options"))
        tabController.tabBarItem = tabBarItem
        var array = self.viewControllers
        array?.append(tabController)
        self.viewControllers = array

    }

}
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • Yes, I create the controller in storyboard. Why did you write tabBarItem and other declarations within a bracket? When I do it, I get an error. Now, I am instantiating using let sb = UIStoryboard(name: "Utility", bundle: nil) let tabController = sb.instantiateViewController(withIdentifier: "MyViewController") as? MyViewController and other lines of code follow this. But still the screen is blank. – A_G May 05 '17 at 09:54
  • The code "within brackets" is inside an `if let` construct, which helps avoid forced-unwrapping and nil optionals. Put a breakpoint on your `let sb = UIStoryboard(name: "Utility", bundle: nil)` line and step through, checking the values of the variables / objects you are creating. See if something is failing. – DonMag May 05 '17 at 12:31
  • Thanks a lot for the help and explanation. The solution worked! – A_G May 09 '17 at 07:24
0

Since you're creating the ViewController programatically ie. without nib/storyboard, you are responsible for instantiating a UIView object and setting the view property of the view controller. to do that implement the loadView method and assign the view object to view property of the viewController. then you can add custom views to the view object, check the code below.

class MyViewController: UIViewController {

    override func loadView() {
        // super.loadView()   // DO NOT CALL SUPER

        //create view
        view = UIView()
        view.backgroundColor = UIColor.white

        //Add a custom view with red color
        let customView = UIView()
        customView.translatesAutoresizingMaskIntoConstraints = false
        customView.backgroundColor = UIColor.red
        view.addSubview(customView)

        NSLayoutConstraint.activate(
            [customView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
             customView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
             customView.topAnchor.constraint(equalTo: view.topAnchor),
             customView.bottomAnchor.constraint(equalTo: view.bottomAnchor)]
        )
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
}

It would be good to use Storyboard/Nib for this purpose as you can easily configure custom views/controls using the autolayout in interface builder rather than doing it programmatically. :)

Edit:

if your'e using storyboard then instantiate view controller like given in below code

class MainScreenTabsController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let tabController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainViewController") as! MainViewController //if using storyboard 
        let icon = UITabBarItem(title: "Menu", UIImage(named: "more-options.png"), selectedImage: UIImage(named: "more-options")))
        tabController.tabBarItem = icon
        var controllers = self.viewControllers
        controllers?.append(tabController)
        self.setViewControllers(controllers!, animated: true)
    }
}
Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
  • I have created UIViewController using a storyboard. and then linked that with my class – A_G May 05 '17 at 09:36
  • have you tried the code without storyboard? if you use storyboard then you need to instantiate view controller using code like let tabController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainViewController") as! MainViewController – Suhit Patil May 05 '17 at 10:49