在同一个应用程序中为不同屏幕制作可重复使用的tableview的最佳方法是什么?

我正在使用类似于Instagram的swift社交ios应用程序。 我有2个屏幕,包含几乎相同的饲料显示。 第一个是包含tableview的简单提要屏幕,第二个是包含配置文件信息的tableview标题的配置文件屏幕,tableview应包含第一个屏幕的相同数据。

我能够做到这一点,但我不得不在第一和第二个屏幕中重复相同的tableview代码:(cellforRow,Number,data和computation ……)

在这种情况下避免重复数据的最佳方法是什么?

您可以通过编写单独的tableview委托和数据源处理程序类来实现此目的,该类可以处理代表视图控制器显示的数据。

处理器:

import UIKit class GenericDataSource: NSObject { let identifier = "CellId" var array: [Any] = [] func registerCells(forTableView tableView: UITableView) { tableView.register(UINib(nibName: "", bundle: nil), forCellReuseIdentifier: identifier) } func loadCell(atIndexPath indexPath: IndexPath, forTableView tableView: UITableView) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) return cell } } // UITableViewDataSource extension GenericDataSource: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 0 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return array.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return self.loadCell(atIndexPath: indexPath, forTableView: tableView) } } // UITableViewDelegate extension GenericDataSource: UITableViewDelegate { func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { } } protocol GenericDataSourceDelegate: class { // Delegate callbacks methods } 

如何与视图控制器一起使用!

 class MyViewControllerA: UIViewController { @IBOutlet weak var tableView: UITableView! var dataSource = GenericDataSource() override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self.dataSource self.tableView.dataSource = self.dataSource } } class MyViewControllerB: UIViewController { @IBOutlet weak var tableView: UITableView! var dataSource = GenericDataSource() override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self.dataSource self.tableView.dataSource = self.dataSource } } 

如果两个tableview包含相同的数据,则可以提取DataSource类来管理数据,将每个重复方法放在此类中,如cellForRow, numberOfRow, cellForRow

然后在viewContoller中,只需初始化DataSource类并设置数据源。

self.tableViewDataSource = DataSource() tableview.dataSource = self.tableViewDataSource

如果两个tableView具有相同的行为,则UITableViewDelegate如此。

我建议实现一个UITableViewCell子类,您可以在其中以编程方式或在.xib进行布局。 在要使用这些单元格的屏幕中,如果以编程方式完成布局,则调用self.tableView.registerClass(MYTableViewCell.self, forCellReuseIdentifier: "cell")self.tableView.registerNib(MYTableViewCell.self, forCellReuseIdentifier: "cell")如果布局是在.xib文件中完成的。

您的类可以有一个configureWithData(data: SomeDataClass)函数,您可以在其中执行所有计算,并使用您在SomeDataClass实例中提供的数据填充单元格。

如果您需要在不同的视图控制器中使用相同的tableview,那么容器视图是最佳选择。

此链接有助于您:

将TableViewController中的TableView嵌入到另一个视图中

Swift表视图嵌入在Container中

 // EventStatus Types enum EventStatusType: String { case ALL = "ALL" case LIVE_NOW = "LIVE_NOW" case HAPPENING_SOON = "HAPPENING_SOON" case COMING_UP = "COMING_UP" case ENDING_NOW = "ENDING_NOW" } class FilterTableHandler: NSObject, UITableViewDelegate,UITableViewDataSource { public typealias FilterTableCallback = ( Int, String ) -> Void private var callback: FilterTableCallback? var filterListArray = [FilterCellObject]() var table : UITableView! override init() { super.init() } func initializeFilterList() { filterListArray.append(FilterCellObject.init(title: "Live Now" , imageName: "filterGreen", querystring: EventStatusType.LIVE_NOW.rawValue, selectionColor: UIColor(red: 0.973, green: 0.996, blue: 0.914, alpha: 1.00))) filterListArray.append(FilterCellObject.init(title: "Happening Soon" , imageName: "filterYellow", querystring: EventStatusType.HAPPENING_SOON.rawValue, selectionColor: UIColor(red: 0.976, green: 0.925, blue: 0.902, alpha: 1.00))) filterListArray.append(FilterCellObject.init(title: "Coming Up" , imageName: "filterOrange", querystring: EventStatusType.COMING_UP.rawValue, selectionColor: UIColor(red: 1.000, green: 0.945, blue: 0.918, alpha: 1.00))) filterListArray.append(FilterCellObject.init(title: "All" , imageName: "", querystring: EventStatusType.ALL.rawValue, selectionColor: UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.00))) } init(tableView: UITableView,callback: @escaping FilterTableCallback) { super.init() initializeFilterList() self.callback = callback table = tableView tableView.allowsSelection = true tableView.separatorStyle = .none tableView.backgroundColor = UIColor.clear tableView.bounces = false tableView.register(UINib(nibName: "FilterTableViewCell", bundle: nil), forCellReuseIdentifier: "FilterTableViewCell") tableView.delegate = self tableView.dataSource = self table.delegate = self table.dataSource = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.filterListArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "FilterTableViewCell", for: indexPath) as! FilterTableViewCell cell.lblTitle.text = self.filterListArray[indexPath.row].title if self.filterListArray[indexPath.row].imageName.isNotEmpty { cell.colorImgView.image = UIImage(named:self.filterListArray[indexPath.row].imageName) } cell.customBackgroundView.backgroundColor = self.filterListArray[indexPath.row].backGroundSelectionColor return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: false) self.callback?(indexPath.row,self.filterListArray[indexPath.row].querystring) } } 

此类处理所有表视图委托和dataSource。 并返回数据。 只需设计TableView并创建该表的IBOutlet,而无需在故事板中添加单元格。 并使用xib创建tableview单元格以使其可重用。

然后,在你的控制器中使用像这样的FilterTableHandler

  var filerHandler = FilterTableHandler.init() self.filerHandler = FilterTableHandler.init(tableView: self.filterTableView, callback: { (index,queryString) in //Your actions on cell selection self.hideFilterView() self.hideInfoView() self.getEventList(queryString: queryString) if index != 3 { //filter option selected self.btnFilter?.setImage(UIImage(named:"filterFilled"), for: .normal) } else { //"all" option selected self.btnFilter?.setImage(UIImage(named:"filter"), for: .normal) } }) 

如图所示初始化FilterTableHandler对象,并使用自定义回调接收选定的数据。 您可以根据自己的要求进行自定义。 tableview变得可以重用整个应用程序。