Nerrolken
Nerrolken

Reputation: 1995

Hiding checkmarks in UITableView multiple selection during Edit Mode

I've got a UITableView which is automatically set up for multiple selection in Edit Mode using the following lines in viewDidLoad:

self.tableView.allowsMultipleSelectionDuringEditing = YES;
[self setEditing:YES animated:YES];

However, I'd like to indicate that a row was selected by changing its background color, rather than by the checkmarks which automatically appear along the left of each row. (For example, the ones that appear when editing the email list in the Mail app, or being discussed in this SO question.) I've got it working for the most part, except that I can't get those checkboxes, which are automatically created as part of putting the UITableView into Edit Mode, to go away.

Below is the code I'm working with:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return _Hierachy.cellCount;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *testCell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if(testCell == nil) {
        testCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    [[testCell textLabel] setText:@"Test Cell"];

    return testCell;
}

Those are the only UITableView methods I've got so far, so everything else should be default behavior.

Does anyone know how to hide those checkmarks along the left, in Edit Mode? I've seen many questions about checkmarks in the accessory portion of the cell, but as I understand it, this is a different thing. I've also seen people talk about the tableView:didSelectRowAtIndexPath: method, but these checkmarks are created when the table enters Edit mode and dismissed when the user taps "Done," so that method doesn't seem related.

The closest I've come is finding this method:

- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath{
    return NO;
}

But that just prevents the cell's content from indenting to make room for the checkmarks. The checkmarks still appear.

Surely there's a way to hide those checkmarks, and still allow multiple selection in Edit Mode? Or are those checkmarks seriously mandatory behavior for a UITableView in Edit Mode with Multiple Selection enabled?

EDIT: I am (reluctantly) open to answers that are somewhat hack-y, like moving the frame of the checkmarks until it's off the screen. This app is for internal use, and won't need to be approved for the App Store. But given that the checkmarks are created automatically when the UITableView moves into Edit Mode, I don't even know how to get them as objects to alter. Any help would be appreciated!

Upvotes: 7

Views: 6049

Answers (3)

Confused Vorlon
Confused Vorlon

Reputation: 10446

here is how to achieve:

  1. swipe to delete works
  2. you don't see the checkbox, delete item or anything else on the left of the cell when in editing mode
  3. Cell indentation still works normally (you can turn this off if you want)
  4. (bonus) Support multiple selection

so - in your UITableViewDelegate

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.isEditing)
    {
      return UITableViewCellEditingStyleNone;
    }
    else
    {
      return UITableViewCellEditingStyleDelete;
    } 
}

- (void)tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{
  (do stuff)
}

you also need to configure your UITableView

self.table.allowsMultipleSelectionDuringEditing=NO;

now if you actually do want multiple selection;

self.table.allowsSelectionDuringEditing=YES;

then manage the selected cells yourself.

I put a custom checkbox in my UITableViewCell subclass, and I also change the value in response to

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

The questioner wants to indicate selection with the background colour - that part should be straightforward.

Upvotes: 0

Razvan
Razvan

Reputation: 4122

You'll have to subclass your UITableViewCell and override the (void)setEditing:animated: method like this:

#import "MyCustomCell.h"

@implementation MyCustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)setSelectedBackgroundView:(UIView *)selectedBackgroundView
{
    //Cell Selected Color: CLEAR
    [super setSelectedBackgroundView:selectedBackgroundView];
}

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    //Cell Edit Mode NO Indent & Selected Color: CLEAR
    [super setEditing:NO animated:animated];
    [self setNeedsLayout];
}

@end

After you do that, go to Inteface Builder and make your cell part of the class MyCustomCell.

After you make your cell part of MyCustomCell class in IB, import MyCustomCell.h in your UITableViewController and modify the following in your code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCustomCell *testCell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if(testCell == nil) {
        testCell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    [[testCell textLabel] setText:@"Test Cell"];

    return testCell;
}

UPDATE: You could also do the following in your TableView's tableView:editingStyleForRowAtIndexPath:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

{
            return UITableViewCellEditingStyleNone;
}

But you will get your cell indented. To remove that indent you'll have to subclass the Cell.

You should be good to go after doing this! I've just tested it and it works the way you want it!

Upvotes: 10

Léo Natan
Léo Natan

Reputation: 57040

Here is the most simple solution for multiple selection with no checkmarks:

- (BOOL)tableView:(UITableView*)tableView canEditRowAtIndexPath:(NSIndexPath*)indexPath {
    return NO;
}

This will cause the cells to be selected using the default selection style (gray or using your custom selection background), and no checkmarks will appear.


A word on whatever solution you pick. Users expect a consistent experience across multiple applications, and these checkmarks are part of this consistency. Make sure to have a good reason to change a normal OS look and feel.

Upvotes: 1

Related Questions