VansFannel
VansFannel

Reputation: 45921

Set an `UIImageView` to not highlighted on a custom UITableViewCell

I'm developing an iOS application with latest SDK.

I have a UITableView with a custom UITableViewCell:

@interface FavouriteCell : UITableViewCell

@property (unsafe_unretained, nonatomic) IBOutlet UIImageView *selectIcon;
@property (unsafe_unretained, nonatomic) IBOutlet UILabel *favName;

@property (nonatomic) BOOL checked;

+ (NSString *)reuseIdentifier;

@end

On selectIcon I set two images from normal and highlighted. When I do cell.checked = !selected; on tableView:didSelectRowAtIndexPath: it works perfectly.

But when I try to reset every selected cell on clearSelectedFavourites:, it doesn't work.

@interface FavViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate, UIAlertViewDelegate>
{
@private
    NSMutableArray* _favsSelected;
    BOOL* _isOnEditingMode;
}

// ######### FavViewController implementation ##############

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        self.title = NSLocalizedString(@"Favoritos", @"Favoritos");
        self.tabBarItem.image = [UIImage imageNamed:@"fav"];

        _favsSelected = [[NSMutableArray alloc] init];
        _isOnEditingMode = NO;

    }
    return self;
}

- (UITableViewCell* )tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"cellForRowAtIndexPath");
    static NSString* CellIdentifier = @"FavCell";

    FavouriteCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"FavouriteCell" owner:self options:nil];
        cell = _favCell;
        self.favCell = nil;
    }

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.favName.font = [UIFont systemFontOfSize:15.0f];

    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

#pragma mark - UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didSelectRowAtIndexPath: %@", indexPath);

    if (tableView.isEditing)
    {
        BOOL selected = NO;

        if ((_favsSelected != nil) && ([_favsSelected count] > 0))
            selected = ([_favsSelected indexOfObject:indexPath] != NSNotFound);

        FavouriteCell* cell =
            (FavouriteCell*)[tableView cellForRowAtIndexPath:indexPath];

        NSLog(cell.checked ? @"Yes" : @"No");
        cell.checked = !selected;

        if (selected)
            [_favsSelected removeObject:indexPath];
        else
            [_favsSelected addObject:indexPath];
    }
}

- (IBAction)editFavList:(id)sender
{
  NSLog(@"edit button clicked!");
    if ([_favList isEditing])
    {
        [self clearSelectedFavourites];
        [_favList setEditing:NO animated:YES];
        [_editButton setImage:[UIImage imageNamed:@"ButtonEdit.png"] forState:UIControlStateNormal];
    }
    else
    {
        [_favList setEditing:YES animated:YES];
        [_editButton setImage:[UIImage imageNamed:@"done_button.png"] forState:UIControlStateNormal];
    }
}

- (void)clearSelectedFavourites
{
    for(int index = 0; index < [_favsSelected count]; index++)
    {
        NSIndexPath* indexPath = (NSIndexPath*)[_favsSelected objectAtIndex:index];

        FavouriteCell* cell = (FavouriteCell*)[self tableView:_favList cellForRowAtIndexPath:indexPath];
        cell.checked = NO;
    }

    [_favsSelected removeAllObjects];
}

- (void)configureCell:(FavouriteCell *)cell
          atIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObject *object = nil;

    object = [self.favListFetchedResultsController objectAtIndexPath:indexPath];

    cell.favName.text = [[object valueForKey:@"name"] description];
}

Do you know why?

I have tried to set selectIcon to not hightlighted manually, but it doesn't work, and that code if the latest test I did.

I have also tested this: [cell setHighlighted:NO]; on clearSelectedFavourites: and it doesn't work.

Upvotes: 1

Views: 546

Answers (2)

Lefteris
Lefteris

Reputation: 14677

You are not showing us your custom [self configureCell:cell atIndexPath:indexPath]; function, so I cannot know what's going on.

However a few things first:

The cells on the TableView are being reused. So you cell select state needs to be set every time for each cell.

Also on your clearSelectedFavourites function, you are getting a reference to all selected cells, then clear their selection, which is pointless, because the cells are going to be reused.

You only need to loop through the visible UITableView cells and change their selection status, then clear your _favsSelected array...

- (void)clearSelectedFavourites
{

    NSArray *cells = [self.tableView visibleCells];
    for (FavouriteCell *cell in cells)
    {
        cell.checked = NO;
        //might not be needed, or might be needed
        [cell setNeedsDisplay];
    }

    [_favsSelected removeAllObjects];
}

Finally on your configureCell function, you should check if the cell should be checked or not, based on your _favsSelected array entries and just select it or not.

Edit

In your configureCell function you should check if the cell needs to be checked or not:

- (void)configureCell:(FavouriteCell *)cell
          atIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObject *object = nil;

    object = [self.favListFetchedResultsController objectAtIndexPath:indexPath];

    cell.favName.text = [[object valueForKey:@"name"] description];
    cell.checked = [_favsSelected containsObject:indexPath];
}

Upvotes: 1

parilogic
parilogic

Reputation: 1179

You can do like this :

[tbl beginUpdates];

/* call you method with animation */

[tbl endUpdates];

[tbl reloadData];

Upvotes: 0

Related Questions