Swift UITableView didSelectRowAtIndexPath方法不被调用

34

我是新手IOS开发者,我在处理表格上的单元格选择时遇到了麻烦。每当我进行选择时,下面的方法就不会被调用 - 有任何想法吗?

我的项目结构如下: 视图控制器->视图->表视图

以下代码演示了方法调用。其他方法可以顺利调用!我知道触摸有效,因为成功下拉刷新并单击单元格后它确实变为高亮。

import UIKit

class ViewController: UIViewController, UITableViewDelegate
{

   let blah = ["blah1"]

   //How many sections are in the table?
   func numberOfSectionsInTableView(tableView: UITableView) -> Int {
      return 1
   }

   //How many rows? (returns and int)
   func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return blah.count
   }

  //table contents for each cell?
  //Each time this is called it'll return the next row and thus build a table...
  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      print("Populating each cell of table view!\n")
      tableView.rowHeight = 80.0
      var cell = UITableViewCell()

      var(a) = blah[indexPath.row]
      var image : UIImage = UIImage(named: a)!
      cell.imageView.image = image

      return cell
  }



  //Code Cell Selected
  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
      println("You selected cell #\(indexPath.row)!")

  }


  func tableView(tableView: UITableViewDelegate, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
     print("wananananaanan" )
     println("You deselected cell #\(indexPath.row)!")

  }




  override func viewDidLoad() {
     super.viewDidLoad()

     // Do any additional setup after loading the view, typically from a nib.

  }

  override func didReceiveMemoryWarning() {
     super.didReceiveMemoryWarning()
     // Dispose of any resources that can be recreated.
  }
}

4
你是否将自己设为表格视图的代理? - Kaan Dedeoglu
13个回答

112

大家都提到要设置tableView的dataSource和delegate。 但是即使设置了,有时候仍然不能正常工作,这可能是由于没有选择或禁用了表格视图的选项。

为了启用它 前往Storyboard -> 选择tableView -> 点击属性检查器 -> 前往选择器 -> 选择单选(或根据需求选择多选)。请参阅附件

请参考附加的截图以便使用。


2
是的,我先禁用它(通过在Storyboard中将Selection设置为None)以便集中精力实现具有自定义单元格的列表,一旦开始处理导航,我忘记了我已经禁用它,花了一些时间才找到在这个答案中突出显示的选项。 - Samuël

44

你需要在你的ViewController中设置一个@IBOutlet,并将它设为tableViewdelegatedataSource,以便您可以查看数据并响应tableView中的更改。

就像这样:

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.delegate = self
    self.tableView.dataSource = self
}

同时还实现了UITableViewDataSource协议。

或者你也可以在界面构建器中将ViewController设置为其代理和数据源(我认为更容易做到),避免像上面的代码一样手动设置。这取决于你。

希望这可以帮到你。


或者,不必子类化 UIViewController,而是使用 UITableViewController - 这样您就可以免费获得许多功能。例如,UITableView 将已为您设置并指向视图控制器的委托。 - Stefan Arentz
谢谢,那个完美地解决了!(我选择了将视图控制器设置为代理输出的快速选项。) - Mark
.delegate = self 对我来说完全解决了这个问题。我很惊讶之前没有这样做。看起来表视图可以在不设置此委托值的情况下打包大量功能。 - Matt Andrzejczuk
各位谷歌员工:在类声明中必须传入 UITableViewDelegate 才能让 .delegate 正常工作!!例如,我的类名为 PickFavVC。这是我在 PickFavVC.swift 中的代码:class PickFavVC: UIViewController, UITableViewDataSource, UITableViewDelegate { - velkoon

18
  • 以下是可以帮助你的几个检查点:

    myTableView.allowsSelection = true

    myTableView.delegate = self

  • 确保你正确地写了 didSelectRowAt

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

  • 如果你在 UITableViewCell 上使用 UIButton,那么它会重叠在单元格上,所以请查看 这里的解决方案


1
在谷歌上搜索了大约30分钟后,你救了我!问题是我在创建表视图时设置了 myTableView.allowsSelection = true,谢谢! - Joshua
1
@konekoya 很高兴我能帮到你。 - Jack

16

SWIFT 3

->

SWIFT 3

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      // Do here
    }

在Swift 3中使用上述委托方法


添加 override。 - Stingalingaling

8

当我比较两个完全相同的代码示例时,遇到了同样的问题,其中一个可以很好地工作,而另一个则无法调用 didSelectRowAtIndexPath

以下是两种可能解决该问题的方法:

1)在代码本身中:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    table.delegate = self
    table.dataSource = self 
//data source might be already set if you see contents of the cells
//the main trick is to set delegate
}

2) 使用StoryBoard或者文档大纲(这是我的问题所在,因为在.swift控制器类中看不到StoryBoard的更改)。

打开文档大纲,并通过Control + 点击你的TableView, 你会看到两个叫做“delegate”和“dataSource”的输出口, 将它们一个接一个地拖到包含ViewController的位置上(就在黄色圆圈上)。

就是这样了!


7

另一个需要注意的问题是轻点手势识别器。在使用表格视图显示多个控制器并处理触摸事件或第一响应者时,通常会使用轻点手势识别器来处理不同的逻辑。

  let tapGesture = UITapGestureRecognizer(target: self, action: #selector(viewTapped))
  view.addGestureRecognizer(tapGesture)

例如,这行代码处理了在我的应用中取消日期选择器,并防止表视图调用didSelectRow委托方法。


2
你需要使用这个方法:首先看看你要扩展什么,然后使用tableView方法。
    class YourViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var mUITableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // We need to tell to UITableView that we will add the data by ourselves
        self.mUITableView.delegate = self
        self.mUITableView.dataSource = self

        // Register the UITableViewCell class with the tableView
        self.mUITableView?.registerClass(UITableViewCell.self, forCellReuseIdentifier: self.cellIdentifier)
        // Setup table data
        getEvents()

        self.mUITableView.allowsSelection = true   
    }

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

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

    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
       //  here to create you cell view      
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        print("You selected cell #\(indexPath.row)!")
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "subtitleCell")
        cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
        cell.textLabel?.text = "\(tableData[indexPath.row].name) - (\(tableData[indexPath.row].eventStateId))"
        cell.detailTextLabel?.text = tableData[indexPath.row].lastUpdate
        return cell
    }
}

2
另一个你可能编写这个函数的原因是允许在特定条件下进行点击。 最初的回答。
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    if(indexPath.section == 1){
        return true
    }
    return false
}

2

还有一个需要注意的地方,可能需要你花费很长时间才能想明白,就是确保你的表格视图(Table View)、单元格(Cell)和内容视图(Content View)都启用了用户交互(User Interaction Enabled)。然后在Swift 4中,至少可以使用以下代码:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

1
如果您正在编辑您的tableView:
tableView.allowsSelectionDuringEditing = true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接