Niels
Niels

Reputation: 125

Animation UITableViewCell backgroundcolor

I have a UITableView with cards in it. If a card is playable, the background color is green, if not, the background color is red. I want this to be animated in a pulsating way and I already managed to do so:

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {


Card *card;
card = [[game playerCards] objectAtIndex:indexPath.row];

if(card.playable == IsPlayable){
[UIView animateKeyframesWithDuration:0.9 delay:0.0 options:UIViewAnimationOptionRepeat |        UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction animations:^{
        cell.backgroundColor = [UIColor colorWithRed:0.105882F green:0.564706F blue:0.243137F alpha:1.0F];
        cell.backgroundColor = [UIColor colorWithRed:0.105882F green:0.564706F blue:0.243137F alpha:0.0F];
                              completion:^(BOOL finished) {           
                              }];}
else if (card.playable == IsNotPlayable){
[UIView animateKeyframesWithDuration:0.9 delay:0.0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction animations:^{
        cell.backgroundColor = [UIColor colorWithRed:1.000000F green:0.000000F blue:0.090196F alpha:1.0F];
        cell.backgroundColor = [UIColor colorWithRed:1.000000F green:0.000000F blue:0.090196F alpha:0.0F];
                              completion:^(BOOL finished) {  
                              }];}
}

It is working really nice, but, the animation is not in sync after scrolling. So when viewdidload is finished, all visible cells are pulsating in sync, but after I scroll the table the animation is not in sync anymore, which gives an ugly effect.

I managed to overcome this, by calling [playerCardsTable reloadData] in scrollViewDidScroll. Now when I scroll the table the animation stops and gives it the correct color in full alpha and when scrolling is stopped it starts pulsating again in sync. This is exactly what I want! But this seems to be a very "expensive way". CPU is peaking at 12% during scrolling (CPU indicator in Xcode). I also tried starting the animation with a Timer, but to no avail.

Should I just go on with reloading the table data during scrolling? Or is there another way? And a side question, is 12% a lot (Mac Mini i7)?

Thanks!

Upvotes: 1

Views: 771

Answers (2)

Armand DOHM
Armand DOHM

Reputation: 1131

Here is my proposal

Add this 2 properties to your controller. This properties will manage the % of alpha

@property CGFloat alpha;
@property CGFloat alphaInc; //alpha will be incremented/decremented by this value

In your viewDidLoad, init the properties, and create a timer for updating the backgrounds

self.alphaInc = 0.01;
self.alpha = 0.1;

[NSTimer scheduledTimerWithTimeInterval:0.05
                                 target:self
                               selector:@selector(updateMyCells)
                               userInfo:nil
                                repeats:YES];

add the method that will update the cells. I've took in consideration your are using a UITableViewController, otherwise please create an iBoutlet for your Table view and name it tableview.

-(void)updateMyCells {
    self.alpha += self.alphaInc;
    if (self.alpha > .5 || self.alpha < .1) {
        self.alphaInc *= -1;
        self.alpha += self.alphaInc;
    }

    [[self.tableView visibleCells] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (obj) {
            UITableViewCell *cell = (UITableViewCell*)obj;
            cell.backgroundColor = [cell.backgroundColor colorWithAlphaComponent:self.alpha];
        }
    }];
}

and finally, adjust your tableView:willDisplayCell:forRowAtIndexPath: :

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    Card *card;
    card = [[game playerCards] objectAtIndex:indexPath.row];

    if(card.playable == IsPlayable){
        cell.backgroundColor = [UIColor colorWithRed:0.105882F green:0.564706F blue:0.243137F alpha:1.0F];
    else {
        cell.backgroundColor = [UIColor colorWithRed:1.000000F green:0.000000F blue:0.090196F alpha:1.0F];
    }
}

Upvotes: 2

ophychius
ophychius

Reputation: 2653

Unfortunately, cells are loaded when you scroll, not when you create the table view. So if you scroll down half a screen the new cells will be out of sync with the ones already shown. You could reload the table data eachtime but that is a somewhat ugly solution. You could try making your own tableview using a scrollview instead. In that case you can load all the subviews (table cells) at once and have them pulsating in sync.

Also, you could make some timer or that fires a notification and let the notification trigger the pulsating in each cell that is visible. That way each new pulsation gets fired by the notification.

Upvotes: 0

Related Questions