在tableview中使用timer会在任何滚动或表重新加载后重新创建计时器

我正在使用https://github.com/mineschan/MZTimerLabel/并在我的Tableview cellForRowAtIndex中使用如下所示的计时器:

UILabel *lblTimer=(UILabel *)[cell viewWithTag:10]; MZTimerLabel *UpgradeTimer = [[MZTimerLabel alloc] initWithLabel:lblTimer andTimerType:MZTimerLabelTypeTimer]; [UpgradeTimer setCountDownTime:timestamp]; [UpgradeTimer startWithEndingBlock:^(NSTimeInterval timestamp) { lblTimer.text = @"✔"; }]; 

但是在任何表重新加载或滚动之后,计时器表现得很奇怪,并且它似乎重新生成多个计时器以便在同一个地方进行计数。 使用此计时器时应该如何解决这个问题?

感谢任何帮助,

埃利亚斯

我看了一下MZTimerLabel ,它严重违反了MVC。 它将属于模型的东西(计算时间的计时器)放入视图中。 这就是你的问题来自哪里。 应该能够重新创建视图而不会对模型产生副作用。

我会建议抛弃那个课程,并创建自己的课程。 实际上很容易实现这样的目标。

  1. 创建一个保存标题和endDate的新类
  2. 将该类的实例存储在支持表的模型中
  3. 创建一个刷新tableView的NSTimer
  4. 设置你的细胞。

这基本上是表格中基本倒计时所需的所有代码。 因为它不会在视图中存储任何数据,所以您可以根据需要滚动:

 @interface Timer : NSObject @property (strong, nonatomic) NSDate *endDate; @property (strong, nonatomic) NSString *title; @end @implementation Timer @end @interface MasterViewController () { NSArray *_objects; NSTimer *_refreshTimer; } @end @implementation MasterViewController - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *modelStore = [NSMutableArray arrayWithCapacity:30]; for (NSInteger i = 0; i < 30; i++) { Timer *timer = [[Timer alloc] init]; timer.endDate = [NSDate dateWithTimeIntervalSinceNow:i*30]; timer.title = [NSString stringWithFormat:@"Timer %ld seconds", (long)i*30]; [modelStore addObject:timer]; } _objects = modelStore; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [_refreshTimer invalidate]; // timer should not exist, but just in case. _refreshTimer = [NSTimer timerWithTimeInterval:0.5f target:self selector:@selector(refreshView:) userInfo:nil repeats:YES]; // should fire while scrolling, so we need to add the timer manually: [[NSRunLoop currentRunLoop] addTimer:_refreshTimer forMode:NSRunLoopCommonModes]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [_refreshTimer invalidate]; _refreshTimer = nil; } - (void)refreshView:(NSTimer *)timer { // only refresh visible cells for (UITableViewCell *cell in [self.tableView visibleCells]) { NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; [self configureCell:cell forRowAtIndexPath:indexPath]; } } #pragma mark - Table View - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _objects.count; } - (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { Timer *timer = _objects[indexPath.row]; cell.textLabel.text = timer.title; NSInteger timeUntilEnd = (NSInteger)[timer.endDate timeIntervalSinceDate:[NSDate date]]; if (timeUntilEnd <= 0) { cell.detailTextLabel.text = @"Finished"; } else { NSInteger seconds = timeUntilEnd % 60; NSInteger minutes = (timeUntilEnd / 60) % 60; NSInteger hours = (timeUntilEnd / 3600); cell.detailTextLabel.text = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds]; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; [self configureCell:cell forRowAtIndexPath:indexPath]; return cell; } @end 

在此处输入图像描述