0

I am going to do my best to explain my problem, so thanks in advance.

I usually build applications with many view controllers by having each ViewController represent a different view. Right now, I am creating a large application with many different views. I do not want to have 15 plus View Controllers in my application. I would rather have one ViewController inherit different UIViews.

For example, if on my menu bar I select the "Settings" option. I would then be taken to the selectionController and have the selectionController inherit the UIView named Settings View

At the moment I am able to navigate to my settingsController and have the Navbar represent the option selected. But how would I go about inheriting the View as well?

When an option is selected this function is called..

//Whatever option selected will affect which view is inherited

    let option = self.menuOptions[indexPath.row]
        if option.name != "Home" {
            self.homeController?.displayController(menuOption: menuOption, view: self.settingsView)
        }

Home Controller

class HomeController: UIViewController {
lazy var menu: Menu = {
    let menuLauncher = Menu()
    menuLauncher.homeController = self
    return menuLauncher
}()

override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.title = "Home"
        view.backgroundColor = Color.blue
        navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(displayMenu))
}

func displayController(menuOption: MenuOption, view: UIView) {
    let selectionController = UIViewController()
    selectionController.navigationItem.title = menuOption.name
    selectionController.view.backgroundColor = Color.blue

//Why dosen't this present the view I have assigned to it??
    selectionController.view.addSubview(HomeView(frame: view.frame))
    navigationController?.navigationBar.tintColor = UIColor.white
    navigationController?.pushViewController(selectionController, animated: true)
}

@objc func displayMenu() {
    menu.displayMenu()
}

}

Gaurav Patel
  • 532
  • 1
  • 5
  • 19
Chandler Long
  • 77
  • 2
  • 11
  • You are presenting the view correctly. I suspect that the frame of `SelectionController` is too small or not set. – Nordeast May 30 '18 at 14:25
  • How would you go about setting it? I thought the frame was its own thing and never needed to be set. – Chandler Long May 30 '18 at 14:29
  • First you should put a break point where you are calling `selectionController.view.addSubview(HomeView(frame: view.frame))` and check the size of both `view.frame` and `selectionController.view.frame`. See if they have a width and height. The frame of the views is configurable to whatever you like. If a `UIViewController` is created from a story board it is the same size as the screen of the device. If you create it in code you need to set it yourself. To set it to the size of the screen you can do `selectionController.view.frame = UIScreen.main.bounds`. – Nordeast May 30 '18 at 14:33
  • Thanks for this! I will try and implement it now. – Chandler Long May 30 '18 at 14:37
  • Thank you for this answer. The UIScreen.main.bounds was what I needed. – Chandler Long May 30 '18 at 16:17

1 Answers1

1

It looks like you're sending in the Settings view here:

self.homeController?.displayController(menuOption: menuOption, view: self.settingsView)

But I don't see where you actually assign that view to a view controller:

func displayController(menuOption: MenuOption, view: UIView) {
    //[...]
    //What is HomeView?  
    selectionController.view.addSubview(HomeView(frame: view.frame))
    //[...]
    navigationController?.pushViewController(selectionController, animated: true)
}

You're passing HomeView to the ViewController, not the passed-in view, and setting HomeView's size to the passed-in view's frame (in this case, Settings).

I would expect something like this:

func displayController(menuOption: MenuOption, view: UIView) {
   let selectionController = UIViewController()
   selectionController.navigationItem.title = menuOption.name
   selectionController.view.backgroundColor = Color.blue

   selectionController.view.addSubview(view)

   navigationController?.navigationBar.tintColor = UIColor.white
   navigationController?.pushViewController(selectionController, animated: true)
}

Not knowing what HomeView does, but assuming it has some other stuff that you want, perhaps the passed-in view would become a subview of HomeView, then HomeView would return what you want. In that case:

 selectionController.view.addSubview(HomeView(selectedView: view))

In this case, HomeView should internally deduce its frame size from the passed-in view, so the frame parameter becomes unnecessary.

Bryan Scott
  • 4,627
  • 1
  • 10
  • 12
  • Beautifully answered! I applied your answer and implemented UIScreen.main.bounds like this: selectionController.view.addSubview(HomeView(selectedView: UIScreen.main.bounds )) It worked like a charm :) – Chandler Long May 30 '18 at 16:16