在Swift中的ViewController中符合协议

时间:2014-06-07 00:13:17

标签: ios protocols swift

尝试在Swift UIViewController子类中符合UITableViewDataSource和UITableViewDelegate。

class GameList: UIViewController {

    var aTableView:UITableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()
        aTableView.delegate = self
        aTableView.dataSource = self
        self.view.addSubview(aTableView)
        //errors on both lines for not conforming
    }

}

文档说你应该遵循class之后的:行,但这通常是超类所在的位置。另一个:不起作用。在超类之后使用以逗号分隔的列表也不起作用

编辑:

下面找到答案。 class GameList: UIViewController, UITableViewDataSource, UITableViewDelegate {

还必须采用每个协议的所有必需方法,这是我最初没有做到的。

6 个答案:

答案 0 :(得分:32)

您使用逗号:

class GameList: UIViewController, UITableViewDelegate, UITableViewDataSource {
    // ...
}

但是要意识到超类必须是逗号分隔列表中的第一项。

如果您未采用协议的所有必需方法,则会出现编译器错误。你必须得到所有必需的方法!

答案 1 :(得分:13)

随着XCode6-Beta7发布,

我注意到UITableViewDataSource的协议方法发生了一些变化,听起来也符合协议错误,这在beta6中运行良好。

这些是根据UITableViewDataSource protocol

实施的必需方法
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // insert code}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // insert code
}

您可能需要重新检查差异或重新实现您认为刚刚实现的委托方法。

答案 2 :(得分:7)

您必须在此处实现两个require方法:

func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int {
    return 10
}

func tableView(tableView:UITableView!, cellForRowAtIndexPath indexPath:NSIndexPath!) -> UITableViewCell! {
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")

    cell.text = "Row #\(indexPath.row)"
    cell.detailTextLabel.text = "Subtitle #\(indexPath.row)"

    return cell
}

答案 3 :(得分:3)

此外,从Delegate类复制所有非可选功能非常重要。 Cmd +单击UITableViewDatasource 并按原样复制这两个定义。

对于beta7中的我来说,UITableViewDatasource有

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

我的实施:

var items = ["Apple", "Pear", "Banana"]

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Default")
    cell.textLabel?.text = items[indexPath.row]
    cell.detailTextLabel?.text = "Test"
    return cell

}

答案 4 :(得分:1)

使用这些方法: 数据源方法有变化 -

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell


protocol UITableViewDataSource : NSObjectProtocol {

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

    // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
    // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell****

    optional func numberOfSectionsInTableView(tableView: UITableView) -> Int // Default is 1 if not implemented

    optional func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different
    optional func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String?

    // Editing

    // Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
    optional func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool

    // Moving/reordering

    // Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
    optional func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool

    // Index

    optional func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! // return list of section titles to display in section index view (e.g. "ABCD...Z#")
    optional func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int // tell table which section corresponds to section title/index (e.g. "B",1))

    // Data manipulation - insert and delete support

    // After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
    // Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
    optional func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)

    // Data manipulation - reorder / moving support

    optional func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
}

Ur代码可以使用!!

答案 5 :(得分:1)

这个问题已经得到解答,但只是想让事情变得更加敏捷。

不是在UITableViewDelegate, UITableViewDataSource中编写协议,而是可以使用extensions 来划分协议,这有助于组织代码。此page

中描述了添加协议一致性

对于上述问题,可以使用扩展名确认协议:

class GameList: UIViewController {
  var aTableView:UITableView = UITableView()
    override func viewDidLoad() {
        super.viewDidLoad()
        aTableView.delegate = self
        aTableView.dataSource = self
        self.view.addSubview(aTableView)
    }
}
extension GameList: UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return list.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
        return cell
    }
}
extension GameList: UITableViewDelegate{
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Row Clicked at \(indexPath.row)")
    }
}