Why is -didDeselectRowAtIndexPath not being called?

匿名 (未验证) 提交于 2019-12-03 09:06:55

问题:

I created a fresh project (Xcode 4, Master-Detail application) just to see if I'm doing something wrong, but I still have the same problem. I want to call -reloadData when the user deselects a cell, so this is my code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {     [tableView deselectRowAtIndexPath:indexPath animated:YES];     NSLog(@"%s", __PRETTY_FUNCTION__); }  -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {     NSLog(@"%s", __PRETTY_FUNCTION__);     [tableView reloadData]; }  -(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {     NSLog(@"%s", __PRETTY_FUNCTION__);     return indexPath; } 

The problem is that didDeselectRowAtIndexPath and willDeselectRowAtIndexPath don't seem to be called. Is this the expected behavior? The docs for tableView:didDeselectRowAtIndexPath: state

Tells the delegate that the specified row is now deselected.

so I guess that it should work as I thought.

回答1:

the documentation of tableView:willDeselectRowAtIndexPath: also says that

This method is only called if there is an existing selection when the user tries to select a different row. The delegate is sent this method for the previously selected row. You can use UITableViewCellSelectionStyleNone to disable the appearance of the cell highlight on touch-down.

It not worked for we when I used UITableViewCellSelectionStyleNone.



回答2:

If you call deselectRowAtIndexPath:animated:, the delegate methods tableView:willDeselectRowAtIndexPath: and tableView:didDeselectRowAtIndexPath: message are not sent.



回答3:

One other quirk that I've found ― in IOS 5.1, at any rate ― is that if you call reloadData on the table, you won't get didDeselectRowAtIndexPath for any selected rows. In my case, I adjust the cell layout slightly depending on whether it's selected or not, so I needed to manually do that work prior to reloading the table data.



回答4:

I know this is an old question but I just ran into the same problem.

If you use

[tableView reloadData] 

Then The table data is reloaded and no rows are selected behind the scenes - meaning

only

didSelectRowAtIndexPath 

is ever called. I hope this helps someone who comes across this problem.



回答5:

A clean way of solving this problem is to do the following:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {     let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)     // Do your cell setup work here...      //If your cell should be selected...     if cellShouldBeSelected {         tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None)     }      return cell } 

This solves this entire problem of a cell not responding to being deselected after a tableView.reloadData()call happens.



回答6:

Set allowsMultipleSelection for that tableview to TRUE

  self.tableView.allowsMultipleSelection = YES; 


回答7:

I think it's just simple mistake! Why don't you use following:

[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 

Instead of using just "tableView" in that line?
I guess, and pretty sure that above line would give you the solution!
hope this helped you, if you looked back at your old question!!!
Kudos! :)



回答8:

When any cell is selected the first time, the -[UITableViewDelegate tableView:didDeselectRowAtIndexPath:] method is not called, but the -[UITableViewDelegate tableView:didSelectRowAtIndexPath:]. Just after selecting one more cell, the didDeselectRowAtIndexPath is called right after the didSelectRowAtIndexPath.

This is OK.

But if you have to show a cell as selected at the begining, (e.q. using UITableViewCellAccessoryCheckmark), then, after selecting another cell you probably want the didDeselectRowAtIndexPath method being called the first time, to deselect the previous cell.

The solution!

You have to call the -[UITableView selectRowAtIndexPath:animated:scrollPosition:] in the -[UITableViewDataSource tableView:cellForRowAtIndexPath:] to notify that a wanted cell is already selected.

Objective-C

#pragma mark - UITableViewDelegate  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {     UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];     cell.accessoryType = UITableViewCellAccessoryCheckmark;     // saving the current selected row     SelectedRow = indexPath.row; }  - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {     UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];     cell.accessoryType = UITableViewCellAccessoryNone; }  #pragma mark - UITableViewDataSource  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];      if (!cell) {         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];     }      // preventing selection style     cell.selectionStyle = UITableViewCellSelectionStyleNone;      cell.textLabel.text = "Some text";      if (indexPath.row == SelectedRow) {         cell.accessoryType = UITableViewCellAccessoryCheckmark;         // just wanted to make it selected, but it also can scroll to the selected position         [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];     }      return cell; } 

Swift 3.1

// MARK: - UITableViewDelegate  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {     let cell = tableView.cellForRow(at: indexPath)!     cell.accessoryType = UITableViewCellAccessoryType.checkmark     selectedRow = indexPath.row }  override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {     let cell = tableView.cellForRow(at: indexPath)!     cell.accessoryType = UITableViewCellAccessoryType.none }  // MARK: - UITableViewDataSource  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {     let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")      // preventing selection style     cell.selectionStyle = UITableViewCellSelectionStyle.none      cell.textLabel?.text = "some text"      if (indexPath.row == selectedRow) {         cell.accessoryType = UITableViewCellAccessoryType.checkmark         // just wanted to make it selected, but it also can scroll to the selected position         tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)     }      return cell } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!