为什么没有调用-didDeselectRowAtIndexPath?

时间:2012-03-22 09:41:13

标签: ios uitableview

我创建了一个新项目(Xcode 4,Master-Detail应用程序),看看我做错了什么,但我仍然遇到同样的问题。我想在用户取消选择一个单元格时调用-reloadData,这是我的代码:

- (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;
}

问题是似乎没有调用didDeselectRowAtIndexPathwillDeselectRowAtIndexPath。这是预期的行为吗? tableView:didDeselectRowAtIndexPath:

的文档
  

告诉委托者现在取消选择指定的行。

所以我猜它应该按照我的想法运作。

10 个答案:

答案 0 :(得分:51)

如果您致电deselectRowAtIndexPath:animated:,则不会发送委托方法tableView:willDeselectRowAtIndexPath:tableView:didDeselectRowAtIndexPath:消息。

答案 1 :(得分:23)

tableView:willDeselectRowAtIndexPath:的文档也说明了

  

只有在存在选择时才会调用此方法   用户尝试选择其他行。委托发送此方法   对于先前选择的行。您可以使用    UITableViewCellSelectionStyleNone 禁用外观   接触时细胞突出显示。

当我使用UITableViewCellSelectionStyleNone时,它对我们无效。

答案 2 :(得分:12)

我在IOS 5.1中发现的另一个怪癖 - 无论如何 - 如果你在桌面上拨打reloadData,你就不会获得didDeselectRowAtIndexPath选定的行。在我的情况下,我根据是否选择了单元格布局,因此我需要在重新加载表格数据之前手动完成这项工作。

答案 3 :(得分:7)

我知道这是一个老问题,但我遇到了同样的问题。

如果您使用

[tableView reloadData]

然后重新加载表数据,并且在幕后没有选择任何行 - 意味着

didSelectRowAtIndexPath

永远被称为。我希望这可以帮助遇到这个问题的人。

答案 4 :(得分:4)

解决此问题的一种简洁方法是执行以下操作:

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
}

这解决了在tableView.reloadData()调用发生后无法响应取消选择的单元格的整个问题。

答案 5 :(得分:1)

第一次选择任何单元格时,不会调用 private static string GetWebText(Uri url) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; request.UserAgent = "A .NET Web Crawler"; WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); StreamReader reader = new StreamReader(stream); string htmlText = reader.ReadToEnd(); return htmlText; } 方法,而是-[UITableViewDelegate tableView:didDeselectRowAtIndexPath:]。在选择了另一个单元格后,-[UITableViewDelegate tableView:didSelectRowAtIndexPath:]后面会调用didDeselectRowAtIndexPath

这没关系。

但是如果你必须在开始时显示一个单元格(eq使用didSelectRowAtIndexPath),那么,在选择另一个单元格后,您可能希望第一次调用UITableViewCellAccessoryCheckmark方法,取消选择上一个单元格。

解决方案!

您必须致电didDeselectRowAtIndexPath中的-[UITableView selectRowAtIndexPath:animated:scrollPosition:],以通知已选择所需的单元格。

<强>目标C

-[UITableViewDataSource tableView:cellForRowAtIndexPath:]

Swift 3.1

#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;
}

答案 6 :(得分:1)

您只需要将选择设置为“多项选择”,因为Xcode仅允许您在此模式下取消选择单元格。

Xcode Screenshot

答案 7 :(得分:0)

将该表格视图的allowsMultipleSelection设置为TRUE

  self.tableView.allowsMultipleSelection = YES;

答案 8 :(得分:0)

我认为这只是一个简单的错误! 你为什么不使用以下内容:

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

而不是只在该行中使用“tableView”?
我想,并且非常肯定上面的那条线会给你解决方案!如果你回头看看你的老问题,希望这对你有帮助!!! 奖励! :)

答案 9 :(得分:0)

对我来说,它是通过添加-> super.setSelected(selected, animated: animated)

开始工作的
override func setSelected(_ selected: Bool, animated: Bool) {
   super.setSelected(selected, animated: animated)//This was missing
}