简体   繁体   中英

Set UITableViewCell selected to YES in willDisplayCell: and the cell can't be deselected anymore

I want to pre-select some rows in a multiple selection UITableView.

I do this in tableView:willDisplayCell:forRowAtIndexPath: by simply setting [cell setSelected:YES animated:NO]; .

However, for some reason this disables deselection for these rows. The embedded controls still work, and so do detail disclosure buttons.

I have uploaded a sample project here: https://github.com/leberwurstsaft/TableViewIssue where you can check out the behavior (in Viewcontroller.m lines 49-51).

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cell setSelected:NO animated:NO]; //   -->   setSelected:YES and the cells can't be deselected anymore...
}

What seems to be the problem?

In addition to setting the cell as selected, you also need to inform the tableView that the cell is selected. Add a call to -tableView:selectRowAtIndexPath:animated:scrollPosition: to your willDisplayCell: method: and you will be able to deselect it as normal.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (/*should be selected */) {
        [cell setSelected:YES animated:NO]; 
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
    }
}

This is similar to @Ivan Loya's solution, but can be done in the same method you were already using. Be sure to use UITableViewScrollPositionNone to avoid odd scrolling behavior.

try this in view did appear, work for me

- (void)viewDidAppear:(BOOL)animated {
    NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
    [_tableView selectRowAtIndexPath:indexPath animated:YES  scrollPosition:UITableViewScrollPositionBottom];
}

in your viewController.h add and link it to the table view

@property (weak, nonatomic) IBOutlet UITableView *tableView;

and comment the line in willDisplayCell Function

I think you should put your selection in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath and toggle in there the selection.

Here is what I do in a similar situation where I want to toggle the checkmark on each row

(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{       
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];

    Person * person = [self.contactTable objectAtIndex:indexPath.row];

        if (newCell.accessoryType == UITableViewCellAccessoryNone)
        {
            newCell.accessoryType = UITableViewCellAccessoryCheckmark;
            person.isMatch = [NSNumber numberWithBool:YES];
            self.countChecked ++ ;


        }else
        {
            newCell.accessoryType = UITableViewCellAccessoryNone;
            person.isMatch = [NSNumber numberWithBool:NO];
            self.countChecked -- ;
        }
}

For those wondering in iOS 11 how to fix this:

Drew C, Got it right, But Im translating it to Swift:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    if cell.isSelected {
        cell.isSelected = true
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM