创建自定义UITableView类

时间:2016-09-08 13:04:30

标签: swift uitableview hierarchy

如何创建包含delegate和dataSource方法的UITableView类的继承人?我不想在我的ViewController中使用dataSource和委托方法。

2 个答案:

答案 0 :(得分:6)

您需要为此目的创建另一个类,但首先让我们看看 ViewController 将如何。

正如您所看到的,代码有点自我解释,我创建了一个名为 TableViewDelegate 的自定义类,它将被设置为委托 dataSource < / strong> tableView

我们传递给 TableViewDelegate 数据将显示在tableView中,功能命名为 didSelectRow 一旦选择了行, TableViewDelegate 将调用它。

class ViewController: UIViewController {

  @IBOutlet weak var tableView: UITableView!

  // data source
  var data = [1, 2, 3, 4]

  // delegate
  var tableViewDelegate: TableViewDelegate?

  override func viewDidLoad() {
    super.viewDidLoad()

    // creating the delegate object and passing the data
    tableViewDelegate = TableViewDelegate(data: data)

    // passing a function to the delegate object
    tableViewDelegate?.didSelectRow = didSelectRow

    // setting the delegate object to tableView
    tableView.delegate = tableViewDelegate
    tableView.dataSource = tableViewDelegate
  }

  // a function that will be called by the delegate object
  // when a row is selected
  func didSelectRow(dataItem: Int, cell: UITableViewCell) {
    let alert = UIAlertController(title: "Info", message: "\(dataItem) was selected.", preferredStyle: .Alert)
    alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
    presentViewController(alert, animated: true, completion: nil)
  }
}

TableViewDelegate ,负责与 UITableViewDelegate UITableViewDataSource 协议相关的所有内容。

class TableViewDelegate: NSObject, UITableViewDelegate, UITableViewDataSource {
  var data = [Int]()

  // variable that holds a stores a function
  // which return Void but accept an Int and a UITableViewCell as arguments.
  var didSelectRow: ((dataItem: Int, cell: UITableViewCell) -> Void)?

  init(data: [Int]) {
    self.data = data
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return data.count
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    let text = String(data[indexPath.row])
    cell.textLabel?.text = text

    return cell
  }

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.cellForRowAtIndexPath(indexPath)!
    let dataItem = data[indexPath.row]

    if let didSelectRow = didSelectRow {
      // Calling didSelectRow that was set in ViewController.
      didSelectRow(dataItem: dataItem, cell: cell)
    }
  }
}

结果:

答案 1 :(得分:1)

我这样做是为了避免使用带有UIPickerViewDelegate / DS的长ViewController。您可以简单地创建一个符合UITableViewDelegate和UITableViewDataSource的类,在视图控制器中实例化该对象,并将其指定为表视图的dataSource和delegate。为了让这个类将东西发送回你的ViewController,你必须为VC提供一个符合的协议,并为该类提供一个委托。

我读到这个类必须从NSObject继承,因为协议是NSObject协议,如果它们没有,它就会引发错误。

class MyCustomTableViewDel: NSObject, UITableViewDataSource, UITableViewDelegate {

    weak var secondaryDelegate: TableViewSecondaryDelegate?
    let rowData: [String]
    init(dataForRows: [String]) {
        rowData = dataForRows
        super.init()
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1


    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{

        return rowData.count

    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        secondaryDelegate?.doSomething(indexPath.row)
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        ....
        return SomeCellForTheTableView
    }

}

然后制作二级协议:

protocol TableViewSecondaryDelegate {
    func doSomething(row: Int)
}

然后在你的ViewController中:

class myTableViewSceneController: UIViewController, TableViewSecondaryDelegate {
    override func viewDidLoad() {
        ....
        let tableViewDelAndDS = MyCustomTableViewDel(dataForRows: ["row0", "row1"])
        tableViewDelAndDS.secondaryDelegate = self
        tableView.delegate = tableViewDelAndDS
        tableView.dataSource = tableViewDelAndDS
    }
        func doSomething(row: Int) { ... }
}