grative
grative

Reputation: 31

How to Organize my ViewScreens on Swift Programmatic UI

I'm learning Programmatic UI and am a little bit obsessed with clean code.

I'm currently building a TabBarVC so that I can manage all of my VC's but I get an error message while doing this.

import UIKit

class MainTabBarVC: UITabBarController {
  
  let firstVC         = FirstVC()
  let secondVC        = SecondVC()
  
  let firstNavVC      = UINavigationController(rootViewController: firstVC)  // Cannot use instance member 'firstVC' within property initializer; property initializers run before 'self' is available
  let secondNavVC     = UINavigationController(rootViewController: secondVC) // Cannot use instance member 'secondVC' within property initializer; property initializers run before 'self' is available
  
  let viewControllers = [firstNavVC, secondNavVC]
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.setupViews()
  }
  
  func setupViews() {
    // Nav Configs
    self.firstVC.view.backgroundColor     = .systemBackground
    self.firstVC.navigationItem.title     = "First Nav"
    
    self.secondVC.view.backgroundColor    = .systemBackground
    self.secondVC.navigationItem.title    = "Second Nav"
    
    // Tab Configs
    self.firstNavVC.tabBarItem.title      = "First TAB"
    
    self.secondNavVC.tabBarItem.title     = "Second TAB"
  }
}

I know if I put firtNavVC, secondNavVC, and viewcontrollers inside the setupViews it is gonna work but I don't like it when one function has too many lines of codes especially when it gets bigger.

So except for my question, are there any extension or enum functions that I can easily manage all of my UINavigationController, UITabBarController, and UIViewController such as enumeration that can call the function whenever I need to call or add a new VC.

Upvotes: -1

Views: 84

Answers (1)

matt
matt

Reputation: 535766

You could change your lets into lazy vars.

class MainTabBarVC: UITabBarController {
  
  lazy var firstVC         = FirstVC()
  lazy var secondVC        = SecondVC()
  
  lazy var firstNavVC      = UINavigationController(rootViewController: firstVC)
  lazy var secondNavVC     = UINavigationController(rootViewController: secondVC)
  
  lazy var viewControllers = [firstNavVC, secondNavVC]
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.setupViews()
  }

However, I think your impulse to maintain instance property references to all these view controllers is mistaken. What I would do is just move the lets into setupViews. You don't need a permanent reference to any of these objects; you just need to create them, configure them, and assign the view controllers as children of your tab bar controller (your code is missing that crucial step, by the way).

Upvotes: 0

Related Questions