Why is -didDeselectRowAtIndexPath not being called?

后端 未结 10 1748
梦如初夏
梦如初夏 2020-11-29 05:38

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

相关标签:
10条回答
  • 2020-11-29 06:22

    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.

    0 讨论(0)
  • 2020-11-29 06:23

    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.

    0 讨论(0)
  • 2020-11-29 06:25

    You just have to set the selection to be "Multiple Selection" as Xcode allow you to deselect the cells in this mode only.

    Xcode Screenshot

    0 讨论(0)
  • 2020-11-29 06:29

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

    0 讨论(0)
  • 2020-11-29 06:29

    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
    }
    
    0 讨论(0)
  • 2020-11-29 06:29

    For me it's started working by adding ->super.setSelected(selected, animated: animated)

    override func setSelected(_ selected: Bool, animated: Bool) {
       super.setSelected(selected, animated: animated)//This was missing
    }
    
    0 讨论(0)
提交回复
热议问题