Nader
Nader

Reputation: 1148

UIViewController multiple inheritance

I have a class called BaseViewController which contains a function where I can add a header to my VC and anchor it

class BaseViewController: UIViewController {

    let headerView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.green
        return view
    }()

    func addHeader() { 
        view.addSubview(headerView)
        // then anchor it to top
    }

}

I have another class called ScrollViewController which adds a scrollViewController to my VC and anchors it

class ScrollViewController: UIViewController {

    let scrollView: UIScrollView = {
        let view = UIScrollView()
        view.backgroundColor = UIColor.green
        return view
    }()

    func addScrollView() { 
        view.addSubview(scrollView)
        // then anchor it to top
    }

}

Finally my main class HomeViewController wants to have both a header and a scrollView so I inherit from both like this:

class HomeViewController: ScrollViewController, BaseViewController {

    override viewDidLoad() {
        super.viewDidLoad()

        addScrollView()
        addHeaderView()

        let view = UIView()
        //anchor view to bottom of the header
    }
}

However swift doesn't allow multiple inheritance so I tried using protocols and extensions which works but the problem is that I want other views to be able to be anchored to the header and scrollView so it didn't fit my needs.

What could I do so I can implement something like that

Thanks

Upvotes: 2

Views: 640

Answers (1)

picciano
picciano

Reputation: 22701

Swift does not support multiple inheritance. However, protocols and protocol extensions can accomplish what you want.

Example:

protocol HeaderProtocol {
    func addHeaderView() -> UIView
}

extension HeaderProtocol where Self: UIViewController {
    func addHeaderView() -> UIView {
        let headerView = UIView()
        headerView.backgroundColor = UIColor.green
        view.addSubview(headerView)
        // then anchor it to top

        return headerView
    }
}

protocol ScrollViewProtocol {
    func addScrollView() -> UIView
}

extension ScrollViewProtocol where Self: UIViewController {
    func addScrollView() -> UIView {
        let scrollView = UIScrollView()
        scrollView.backgroundColor = UIColor.green
        view.addSubview(scrollView)
        // then anchor it to top

        return scrollView
    }
}

class HomeViewController: UIViewController, ScrollViewProtocol, HeaderProtocol {
    override func viewDidLoad() {
        super.viewDidLoad()

        let scrollView = addScrollView()
        let headerView = addHeaderView()
    }
}

Alternative approach:

protocol HeaderProtocol {
    var headerView: UIView? { get set }
    func addHeaderView() -> UIView
}

extension HeaderProtocol where Self: UIViewController {
    func addHeaderView() -> UIView {
        let headerView = UIView()
        headerView.backgroundColor = UIColor.green
        view.addSubview(headerView)
        // then anchor it to top

        return headerView
    }
}

protocol ScrollViewProtocol {
    var scrollView: UIView? { get set }
    func addScrollView() -> UIView
}

extension ScrollViewProtocol where Self: UIViewController {
    func addScrollView() -> UIView {
        let scrollView = UIScrollView()
        scrollView.backgroundColor = UIColor.green
        view.addSubview(scrollView)
        // then anchor it to top

        return scrollView
    }
}

class HomeViewController: UIViewController, ScrollViewProtocol, HeaderProtocol {
    var scrollView: UIView?
    var headerView: UIView?

    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView = addScrollView()
        headerView = addHeaderView()
    }
}

Upvotes: 4

Related Questions