无法避免子类化

时间:2018-09-24 13:35:14

标签: ios swift subclass

我有一个带有多个视图控制器的应用程序。我正在实现一个搜索栏,以浏览每个视图控制器中的表视图

我选择使用自定义类来实现搜索控制器,在该类中我将处理所有搜索逻辑。为了使之成为可能,我目前正在使用每个视图控制器都继承自的超类。我想知道是否有一种方法可以使我无需子类化。

这是我的SearchController类的当前实现:

class SearchController: NSObject, UISearchBarDelegate {

    /* This is the trouble spot. If I change this to UIViewController?, 
       I get the compiler error "value of type UIViewController has no member tableView" */
    weak var viewController: BaseViewController?  

    /*
      ... rest of SearchController implementation

      includes methods that interact with view controller table views
    */
}

这是BaseViewController类:

class BaseViewController: UIViewController {

    let searchController = SearchController()
    let tableView = UITableView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)

    /*
      ... rest of BaseViewController implementation
    */

}

总而言之,我遇到的问题是我有几个带有表视图的视图控制器,而且如果不创建它们可以继承的新基类,我似乎就无法完成这项工作。使用UIViewController根本行不通,因为UIViewController类没有内置tableView属性。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您无需强制所有viewControllers继承BaseViewController的子类。如果唯一的要求是viewController具有tableView属性,则使用该要求定义一个协议,并使相关的viewController实现该协议。 重写示例:

protocol BaseControllerProtocol: class {
    var tableview: UITableView { get }
}

class SearchController: NSObject, UISearchBarDelegate {

    //We store any class that implements the BaseControllerProtocol protocol
    //Now you can use viewController.tableview
    weak var viewController: BaseControllerProtocol?
    //If you what to have UIViewcontrollers instances only use:
    //weak var viewController: (UIViewController & BaseControllerProtocol)?
}

//An example of a viewcontroller that implements the BaseControllerProtocol
class ARandomViewController : UIViewController, BaseControllerProtocol {
    var tableview: UITableView = UITableView()
}

答案 1 :(得分:0)

我认为,如果您将UIViewController?分配给UITableView的私有SearchViewController计算实例变量,则仍然可以使用tableView

class SearchController: NSObject, UISearchBarDelegate {
    weak var viewController: UIViewController?

    fileprivate var _tableView: UITableView? {
        if let vc = self.viewController {
            for subview in vc.view.subviews {
                if let tableView = subview as? UITableView {
                    return tableView
                }
            }
        }
        return nil
    }

    // Whatever methods interact with table view should now use self._tableView.
    func doSomething() {
        guard let tableView = self._tableView else { return }
        // Do something with the tableView
    }
}