0

I have a problem which should be a trivial one but I still can't find a good solution to it.

I have a tableView in which I store cells representing different threads/chatrooms. I have an NSArray with data for cells/chats. I want to display a badge (with a custom badgeCell) indicating a new message on a corresponding cell.

When I receive a push notification my method searches through the cells and finds indexPath for a cell connected with that new message and adds it to NSArray. Then I reload the tableView.

In tableView:willDisplayCell:forRowAtIndexPath: I check if the cells' indexPath is inside that NSArray of indices and if so I display a badge.

Everything works just fine until I scroll tableView so the cell is not visible. When it comes back again it doesn't have any badge. Also if my cell is not visible when the Push Notification comes it also doesn't display the badge.

I know it has something to do with ReuseIdentifiers but I can't think of any good solution. Please help me !

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier1 = @"MyCell";

    ProblemsTableViewCell *cell;
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
    if(!cell) {
        cell = [[ProblemsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
    }    
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        cell.separatorInset = UIEdgeInsetsZero;
    }

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray];

    cell.delegate = self;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    [cell.contentView.superview setClipsToBounds:NO];
    [cell.contentView setClipsToBounds:NO];
    cell.clipsToBounds = NO;

    return cell;
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(nonnull UITableViewCell *)cell forRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
    ProblemsTableViewCell * Cell = (ProblemsTableViewCell*)cell;

    /* … some customization - > backgroundColor/images etc. … */         
    for(NSIndexPath* index in self.newMessages){
        if(indexPath.row == index.row){
            Cell.badgeString = @"new message";  // the _badge property is a built in view of a custom Cell class with a badge.
            Cell.badgeColor = [UIColor whiteColor];
            Cell.badgeColorHighlighted = [UIColor whiteColor];
            Cell.badge.radius = 0;
            Cell.badge.fontSize = 15;
            Cell.badge.layer.opacity = 0.55f;

            NSLog(@"update 0");
            break;
        }
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Bartek Uchański
  • 119
  • 1
  • 12
  • Can you post your code for `tableView:willDisplayCell:forRowAtIndexPath:` and `tableView:cellForRowAtIndexPath:`? – Greg Brown Dec 11 '15 at 15:16
  • Please look at the edit. – Bartek Uchański Dec 11 '15 at 15:32
  • Might it have something to do with the custom delegate you are setting on the cell? What does this delegate do? Also, is there any reason you put the badging logic in `tableView:willDisplayCell:forRowAtIndexPath:` instead of just doing everything in `tableView:cellForRowAtIndexPath:`? – Greg Brown Dec 11 '15 at 15:46
  • I'm not sure if there's a reason you didn't do it this way to begin with, but it seems like a better approach might be to maintain an array of objects representing your cell contents and add a "new" property to this class. That way, when you dequeue a cell, you can just check the "new" property and badge the icon as needed. – Greg Brown Dec 11 '15 at 15:50
  • If you must keep the list of new items in a separate array, I'd suggest sorting them by index path (section, row). That way, you can do a binary search to see if an index path is in the array instead of a sequential scan. – Greg Brown Dec 11 '15 at 15:51

1 Answers1

1

Instead of trying to maintain an array of indices, use the array with cell data. Add an indicator for each element in there to say whether a badge is needed or not and use it to turn the badge on or off during cellForRowAtIndexPath.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57