Reputation: 125
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
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
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