我有一个带有多个视图控制器的应用程序。我正在实现一个搜索栏,以浏览每个视图控制器中的表视图。
我选择使用自定义类来实现搜索控制器,在该类中我将处理所有搜索逻辑。为了使之成为可能,我目前正在使用每个视图控制器都继承自的超类。我想知道是否有一种方法可以使我无需子类化。
这是我的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
属性。
有什么想法吗?
答案 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
}
}