【问题标题】:Conform to protocol in ViewController, in Swift在 Swift 中符合 ViewController 中的协议
【发布时间】:2014-07-28 08:16:12
【问题描述】:

试图在 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 行,但这通常是超类所在的位置。另一个: 不起作用。在超类之后使用逗号分隔的列表也不起作用

编辑:

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

【问题讨论】:

    标签: ios protocols swift


    【解决方案1】:

    你使用逗号:

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

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

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

    【讨论】:

    • 我仍然收到错误,但现在错误出现在class 行。它说类型“GameList”不符合协议“UITableViewDataSource”
    • @JustinAmberson,是的,那是因为您还没有完全实现成为UITableViewDataSource 所需的所有方法。一旦你添加了所需的方法,错误就会消失!
    • 哇,但我认为只有其中一些是@required。 cellForRow, numberOfSections, numberOfRowsInSection
    • 嘿,你是对的。我以为我拥有它们,但我没有在 numberOfSections 上正确的方法签名
    【解决方案2】:

    你必须在这里实现两个 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】:

      随着 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
      }
      

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

      【讨论】:

      • 是的,他们更改了方法名称。删除感叹号(隐式展开可选)。实现新方法名称效果很好。
      • 如果有人实现了这些方法但仍然出现错误,我在清理时摆脱了它。这让我很烦恼一段时间,但错误消失了
      【解决方案4】:

      此外,从 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
      
      }
      

      【讨论】:

        【解决方案5】:

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

        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)
        }
        

        你的代码可以工作!!

        【讨论】:

          【解决方案6】:

          这个问题已经回答了,但只是想让事情变得更快捷一些。

          不用在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)")
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2016-05-05
            • 1970-01-01
            • 2016-11-17
            • 2014-11-08
            • 1970-01-01
            • 1970-01-01
            • 2017-11-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多