Can I use a super class to push to a new view controller which is also inherited?

149 views Asked by At

I have two super view controllers MasterCategoryListViewController and MasterCategoryItemViewController.

I want to use these in several apps.

I inherit from both of these

class CustomListController: MasterCategoryListViewController
class CustomItemController: MasterCategoryItemViewController

Now in the MasterCategoryListViewController

I have a button handler...

@objc open func btnAddTapped(sender: UIBarButtonItem) {
    let itemViewController = MasterCategoryItemViewController()
    itemViewController.title = "Type"
    self.navigationController?.pushViewController(itemViewController, animated: true)
}

I know I can override the method to push to CustomItemController however, I'm just wondering if I can do this in my MasterCategoryListViewController, obviously without it knowing anything about what CustomItemController?

2

There are 2 answers

0
danh On BEST ANSWER

Create a method on the parent called something like detailVCClass(), answering the class that should be instantiated upon button tap. The parent can answer something generic, and the subclasses answer any class that's appropriate for each to know about.

Have the button tap method instantiate an instance of self.detailVCClass(), rather than a class name literal.

0
Glenn Posadas On

however, I'm just wondering if I can do this in my MasterCategoryListViewController, obviously without it knowing anything about what CustomItemController ?

Yes. Why not? However, the one that will be pushed is the MasterCategoryItemViewController, not any subclassing classes of it. So like what you've mentioned in your question, you know that btnAddTapped can be overriden, so do it like that.

OR, you could do something a bit more interesting:

In your MasterCategoryListViewController, have an object of MasterCategoryItemViewController. Then in your CustomListController, apply any subclassing MasterCategoryListViewController class. Next, push that MasterCategoryItemViewController object in your btnAddTapped()

Complete sample:

import UIKit

class ListVC: MasterListVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "ListVC"
        self.itemVCToBePushed = ItemVC2()
    }
}

class MasterListVC: UIViewController {

    var itemVCToBePushed: MasterItemVC?

    lazy var button: UIButton = {
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 100, y: 100, width: 250.0, height: 44.0)
        button.setTitle("Test", for: .normal)
        button.addTarget(self, action: #selector(self.pushMe), for: .touchUpInside)
        button.backgroundColor = .gray
        return button
    }()

    @objc func pushMe() {
        guard let itemVCToBePushed = self.itemVCToBePushed else { return }
        self.navigationController?.pushViewController(itemVCToBePushed, animated: true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "MasterListVC"
        self.view.backgroundColor = .white

        self.view.addSubview(self.button)
    }
}

/////

class ItemVC: MasterItemVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "ItemVC"
    }
}

class ItemVC2: MasterItemVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "ItemVC2"
    }
}

class MasterItemVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "MasterItemVC"
        self.view.backgroundColor = .white
    }
}