背景:项目里需要实现每一行展示数据里面都有一个倒计时显示,倒计时结束,显示“已结束”
思路:
1、从服务器获取数据以后,启用定时器
2、定时器方法主要功能:
(1)更新数据源中的倒计时字段信息
(2)获取正在页面显示的cell,用来更新展示页面
界面展示:
plist文件:
代码如下:
#import "ViewController.h"
#import <objc/runtime.h>
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong)NSMutableArray <NSMutableDictionary *>*dataArray;
@property (nonatomic, strong)NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//从plist文件中加载数据源
[self loadDataSource];
}
- (void)loadDataSource{
NSString *dataPath = [[NSBundle mainBundle] pathForResource:@"dataList" ofType:@"plist"];
self.dataArray = [[NSMutableArray alloc] initWithContentsOfFile:dataPath];
if (self.dataArray) {
[self startTimer];
}
}
#pragma mark - 计时器
- (void)startTimer{
if (self.timer == nil) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(refreshTime) userInfo:nil repeats:YES];
//如果不添加这条语句,在UITableView拖动的时候,会阻塞定时器的调用
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:UITrackingRunLoopMode];
}
}
- (void)endTimer{
if(self.timer && self.timer.isValid){
[self.timer invalidate];
self.timer = nil;
}
}
- (void)refreshTime{
long long time;
int unvaliableCount = 0;
for (int i = 0; i < self.dataArray.count; i++) {
NSMutableDictionary *dict = self.dataArray[i];
time = [dict[@"leftDate"] longLongValue];
if (time == 0) {
++unvaliableCount;
continue;
}
time = time - 1000;
dict[@"leftDate"] = [NSNumber numberWithLongLong:time];
}
NSMutableArray *visibleCell = [self.tableView valueForKey:@"_visibleCells"];
for (UITableViewCell *cell in visibleCell) {
NSMutableDictionary *dict = [self.dataArray objectAtIndex:cell.tag];
long long cellTime = [dict[@"leftDate"] longLongValue];
cell.detailTextLabel.text = [self getResuableTime:cellTime];
}
//所有倒计时结束,计时器销毁
if (unvaliableCount == self.dataArray.count) {
[self endTimer];
}
}
- (NSString *)getResuableTime:(long long)timeValue{
if(timeValue <= 0){
return @"已结束";
}else{
NSUInteger time = timeValue / 1000;
NSUInteger hour = (NSUInteger)(time/3600);
NSUInteger min = (NSUInteger)(time%(3600))/60;
NSUInteger second = (NSUInteger)(time%60);
NSString *timeString = [NSString stringWithFormat:@"%02lu:%02lu:%02lu",(unsigned long)hour,(unsigned long)min,(unsigned long)second];
return timeString;
}
}
#pragma mark - UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"demoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
cell.tag = indexPath.row;
NSMutableDictionary *dict = [self.dataArray objectAtIndex:indexPath.row];
cell.textLabel.text = dict[@"title"];
long long cellTime = [dict[@"leftDate"] longLongValue];
cell.detailTextLabel.text = [self getResuableTime:cellTime];
return cell;
}
//查看UITableView属性
- (IBAction)printBtnAction:(UIButton *)sender {
unsigned int count = 0;
Ivar *members = class_copyIvarList([UITableView class], &count);
for (int i = 0; i < count; i++) {
Ivar var = members[i];
const char *memberName = ivar_getName(var);
const char *memberType = ivar_getTypeEncoding(var);
NSLog(@"%s : %s",memberName,memberType);
}
NSLog(@"总数 %d",count);
}
@end