首页 > 解决方案 > UIViewController 多重继承

问题描述

我有一个名为的类BaseViewController,其中包含一个函数,我可以在其中向我的 VC 添加标头并锚定它

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
    }

}

我有另一个名为的类ScrollViewController,它将一个 scrollViewController 添加到我的 VC 并锚定它

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
    }

}

最后我的主类HomeViewController想要同时拥有一个标题和一个滚动视图,所以我从两者继承如下:

class HomeViewController: ScrollViewController, BaseViewController {

    override viewDidLoad() {
        super.viewDidLoad()

        addScrollView()
        addHeaderView()

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

然而 swift 不允许多重继承,所以我尝试使用有效的协议和扩展,但问题是我希望其他视图能够锚定到标题和滚动视图,所以它不符合我的需要。

我该怎么做才能实现类似的东西

谢谢

标签: iosswiftprotocolsmultiple-inheritance

解决方案


Swift 不支持多重继承。但是,协议和协议扩展可以完成您想要的。

例子:

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()
    }
}

替代方法:

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()
    }
}

推荐阅读