2014-04-21 11 views
5

sto usando https://github.com/mineschan/MZTimerLabel/ e nella mia Tableview cellForRowAtIndex con il timer come di seguito:Utilizzando timer in un Tableview ri crea il timer dopo ogni rotolo o un tavolo ricarica

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

Ma dopo qualsiasi tavolo ricarico o lo scorrimento, il timer si comporta in modo strano e sembra rigenerare più timer per contare nello stesso posto. Come devo risolvere questo problema mentre utilizzo questo timer?

Apprezzo tutto l'aiuto,

Elias

+0

Cosa si vuole raggiungere? Poiché 'tableView: cellForRowAtIndexPath:' sarà chiamato ogni volta che viene visualizzata una cella, non si deve usare un timer. –

+0

Ho un pulsante di aggiornamento nel mio tableviewCell e quando l'utente tocca il pulsante dovrei sostituire il pulsante con un conto alla rovescia. Anche l'elenco a volte deve essere ricaricato perché i dati provengono da un servizio web. –

+0

Se si utilizzano celle personalizzate, è possibile aggiungere un pulsante nella cella e nasconderlo al clic e mostrare un timer. – iBug

risposta

8

ho dato un'occhiata a MZTimerLabel, e viola MVC male. Mette qualcosa che appartiene al modello (il timer che conta giù nel tempo) nella vista. Ecco da dove viene il tuo problema. Le viste dovrebbero poter essere ricreate senza effetti collaterali sul modello.

Consiglierei di abbandonare quella classe e crearne una propria. In realtà è abbastanza facile ottenere qualcosa di simile.

  1. creare una nuova classe che salva un titolo e un endDate
  2. memorizzare istanze di quella classe nel modello che esegue il vostro tavolo
  3. Creare uno NSTimer che rinfresca la tableView
  4. Impostare la vostra le cellule.

Questo è praticamente tutto il codice necessario per un conto alla rovescia di base in una tabella. Perché non memorizza alcun dato nella visualizzazione è possibile scorrere il più vi piace:

@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 

enter image description here

+0

Grazie mille. Le mie lezioni sono così grandi e complicate, ci vuole un po 'di tempo per provare la soluzione. Sto iniziando a usarlo e accetterò la tua risposta dopo aver finito. Grazie. –

+0

Fantastico! Completamente funzionato. Grazie mille amico. –

+0

Ciao Matthias, sono stato reindirizzato alla tua domanda tramite il mio link precedente qui: http://stackoverflow.com/questions/29961244/set-uitableviewcell-contents-only-once. Ho fatto funzionare il tuo timer e funziona bene. Tuttavia, i tempi si aggiornano solo quando si scorre su e giù per 'UITableView'. C'è un modo per farli rinfrescare in tempo reale? Significa che l'utente può vedere i tempi che scendono ogni secondo. Se tu potessi aiutarmi, sarebbe fantastico. Grazie! – user1871869