0
votes

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 view controller represent a different view. Right now, I am creating a large application with many different views. I do not want to have 15 plus viewControllers in my application. I would rather have one view controller 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 SettingsView as well?

HomeController

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) {
        let selectionController = UIViewController()
        selectionController.navigationItem.title = menuOption.name
        selectionController.view.backgroundColor = Color.blue
        navigationController?.navigationBar.tintColor = UIColor.white
        navigationController?.pushViewController(selectionController, animated: true)
    }

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

MenuView

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return menuOptions.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell
    let menuOption = menuOptions[indexPath.row]
    cell.menuOption = menuOption
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectionView.frame.width, height: 30)
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let menuOption = self.menuOptions[indexPath.row]
    print(menuOption.name)
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
        self.blackView.alpha = 0

        if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
            let width = window.frame.width - 150

            self.menuView.frame = CGRect(x: -width, y: 0, width: 0, height: window.frame.height)
        }

    }) { (completed: Bool) in


//THIS IS WHERE I CALL MY FUNCTION TO SET UP THE SELECTIONCONTROLLER
        self.homeController?.displayController(menuOption: menuOption)
    }
}

override init(frame: CGRect) {
    super.init(frame: frame)
    self.collectionView.delegate = self
    self.collectionView.dataSource = self
    collectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)

    setUpView()
    setUpCollectionView()

}

After an option is selected (In the form of an index path), and after the menu animation is finished. I call my function displayController in the HomeController and set up the new controller.

How would I implement a view also? If I selected "Settings", how can I get the selectionController to display the SettingsView as well?

2

2 Answers

0
votes

You can add a subview to an existing view:

//The container view can be in the vc with constraints already setup.
//Or you can use the vc's default view.
enum MyView: Int { case settingsView = 0, otherView }

//Add view
let view = UIView(frame: containerView.bounds)
view.tag = MyView.settingsView.rawValue
containerView.addSubview(view)

//Remove view
if let remove = containerView.viewWithTag(MyView.settingsView.rawValue) {
    remove.removeFromSuperview()
}
0
votes

Personally I don't think having many ViewController is a problem. It gives couple of bonuses like life cycle control to the view which you can take advantage of.

A good explanation: https://stackoverflow.com/a/30459226/7591205

When the view is getting complicated, it's better to get encapsulated into ViewController.

But if you are sticking to having multiple View for 1 ViewController. What I would suggest is having a container view concept then switch your views inside of it. A good way to achieve that is having a UIStackView then put all of your views in there. Then hide/show by your needs.