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

时间:2017-04-10 09:06:10

标签: ios swift swift3 tableview

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

我能够做到这一点,但我必须在第一和第二屏幕中重复相同的tableview代码: (cellforRow,数字,数据和计算...)

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

5 个答案:

答案 0 :(得分:5)

您可以通过编写单独的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
    }
}

答案 1 :(得分:0)

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

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

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

此链接有助于您:

Embedding TableView in TableViewController into another view

Swift table view Embedded in Container

答案 4 :(得分:-1)

// 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可以重复使用整个应用程序。