我想知道在相当复杂的UITableViewCells中显示倒计时的正确方法是什么,在每个单元格中有不同时间倒计时。
我可以单独为每个细胞分别使用NSTimer,但是细胞不会同时更新。我可以为所有单元格提供一个NSTimer但是在uitableview上调用reloadData每秒都要花费相当多,不是吗?
显然需要仅在可见单元格中进行更新。
任何想法,最佳实践,知道如何解决这个问题?
答案 0 :(得分:6)
关于如何实现这一点的一些想法:
update
方法。此方法更新标签。TableViewController
类indexPath
遍历单元格。对于不可见的单元格,UITableView.CellForRowAtIndexPath
会返回nil
。update
方法。答案 1 :(得分:2)
另一种方法是使用NSNotificationCenter
。
您的视图控制器会在您的时间段过去后发布通知。
您的每个UITableViewCell都会注册此通知并更新其显示作为回应。
请注意,为防止内存泄漏,您需要将每个UITableViewCell作为观察者移除,因为它会离开屏幕。这可以在UITableViewDelegate
中轻松完成
tableView:didEndDisplayingCell:forRowAtIndexPath:
方法。
这样做的好处是您不需要继承UITableViewCell,也不需要尝试跟踪需要刷新的每个单元格。
答案 2 :(得分:0)
在cellForRowAtIndexPath中,存储对所需每个单元格的引用。
if (indexPath.row == indexPath1.row) {
_timerCell1 = cell;
} else if (indexPath.row == indexPath2.row) {
_timerCell2 = cell;
} ...
安排计时器以在需要更新该单元时更新每个单元格。
_timer1 = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateCell1) userInfo:nil repeats:true];
_timer2 = [NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(updateCell2) userInfo:nil repeats:true];
这消除了对tableView的任何更新的需要。
答案 3 :(得分:-1)
From the image, it looks like your model is a set of actions the user plans to take. I would arrange things this way:
1) MyAction is an NSObject with a name and a due date. MyAction implements something like this:
- (NSString *)timeRemainingString {
NSDate *now = [NSDate date];
NSTimeInterval secondsLeft = [self.dueDate timeIntervalSinceDate:now];
// divide by 60, 3600, etc to make a pretty string with colons
// just to get things going, for now, do something simple
NSString *answer = [NSString stringWithFormat:@"seconds left = %f", secondsLeft];
return answer;
}
2) StatusViewController keeps a handle to the model which is an NSArray of MyActions, it also has an NSTimer (just one) that tells it time is passing.
// schedule timer on viewDidAppear
// invalidate on viewWillDisappear
- (void)timerFired:(NSTimer *)timer {
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.model.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyAction *myAction = [self.model objectAtIndex:indexPath.row];
// this can be a custom cell. to get it working at first,
// maybe start with the default properties of a UITableViewCell
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [myAction timeRemainingString];
cell.detailTextLabel.text = [myAction name];
}