电商上很多需求都有倒计时功能。如果每个cell上加个定时器,性能上不好,所以这个问题不太好解决。借鉴了下别人思路写了了demo。
思路:
- 首先在控制器里设置一个定时器,就一个定时器就够了。
- 在定时器的执行方法里。把所有的后台返回的秒数减一。这是控制数据源。等着下次滑动的时候秒数就减少了。然后发通知给cell。让cell里的显示秒数的label变化。
上代码TimeCell
#import <UIKit/UIKit.h>
#define TimeCellNotification @"NotificationTimeCell"
@interface TimeCell : UITableViewCell
//作用是只是刷新显示在屏幕上的时间
@property(nonatomic,assign)BOOL isDisplay;
- (void)setSecond:(NSNumber *)second row:(NSInteger) row;
@end
#import "TimeCell.h"
@interface TimeCell ()
@property(nonatomic,strong)UILabel *titleLabel;
@property(nonatomic,strong)UILabel *timeLabel;
@property(nonatomic,strong)NSNumber *time;
@property(nonatomic,assign)NSInteger row;
@end
@implementation TimeCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(notificationCenterEvent)
name:TimeCellNotification
object:nil];
[self loadUI];
}
return self;
}
- (void)loadUI
{
self.titleLabel = [[UILabel alloc]init];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.titleLabel.textColor = [UIColor blackColor];
[self.contentView addSubview:self.titleLabel];
self.timeLabel = [[UILabel alloc]init];
self.timeLabel.textAlignment = NSTextAlignmentCenter;
self.timeLabel.textColor = [UIColor blackColor];
[self.contentView addSubview:self.timeLabel];
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.titleLabel.frame = CGRectMake(0, 0, 100, 50);
self.timeLabel.frame = CGRectMake(self.frame.size.width-100, 0, 100, 50);
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)setSecond:(NSNumber *)second row:(NSInteger) row
{
self.time = second;
self.row = row;
self.timeLabel.text = [self currentTimeString];
self.titleLabel.text = [NSString stringWithFormat:@"%ld",row];
}
- (NSString*)currentTimeString {
NSInteger second = [self.time integerValue];
if (second <= 0) {
return @"00:00:00";
} else {
return [NSString stringWithFormat:@"%02ld:%02ld:%02ld",(long)second/3600,(long)second%3600/60,(long)second%60];
}
}
- (void)notificationCenterEvent{
if (self.isDisplay) {
self.time = @([self.time integerValue] - 1);
[self setSecond:self.time row:self.row];
}
}
@end
控制器代码
#import "ViewController.h"
#import "TimeCell.h"
static NSString *cellID = @"cellID";
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@property(nonatomic,strong)UITableView *tableView;
@property(nonatomic,strong)NSMutableArray *dataArray;
@property(nonatomic,strong)NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArray = [NSMutableArray array];
for (int i=0; i<30; i++) {
NSInteger second = 100 + arc4random_uniform(1000);
[self.dataArray addObject:@(second)];
}
self.tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[TimeCell class] forCellReuseIdentifier:cellID];
[self.view addSubview:self.tableView];
self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timeAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TimeCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
[cell setSecond:self.dataArray[indexPath.row] row:indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 50;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
TimeCell *timeCell = (TimeCell *)cell;
timeCell.isDisplay = YES;
[timeCell setSecond:self.dataArray[indexPath.row] row:indexPath.row];
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath
{
TimeCell *timeCell = (TimeCell *)cell;
timeCell.isDisplay = NO;
}
- (void)timeAction
{
for (int i=0; i<self.dataArray.count; i++) {
NSInteger second = [self.dataArray[i] integerValue];
second = second - 1;
self.dataArray[i] = @(second);
}
[[NSNotificationCenter defaultCenter] postNotificationName:TimeCellNotification object:nil];
}
@end