Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to refresh TableView Cell data during an NSTimer loop
    primarykey
    data
    text
    <p>Disclaimer: I'm a new convert to iOS, so please feel free to tell me that my whole approach is wrong. I only ask that you explain why -- my goal here is to learn (and, of course, also to solve this problem).</p> <p>...</p> <p>Hi all, I'm new to iOS programming and after trying to solve this problem for several hours, my ignorance and cocoa inexperience is getting the best of me. Hoping I can find some help here.</p> <p>I've got a simple TableView App I'm working on as a sandbox for a larger app that's in the works. The functionality I'm trying to achieve right now is a pseudo real-time update of the subtitle text in a TableView Cell (i.e. cell.detailTextLabel.text ).</p> <p>To give you a better idea of the goal: I'm trying to make it so the user can tap the TableView cell and a "stopwatch" style timer starts counting up in the subtitle text.</p> <p>But I can't figure out how to update cell.detailTextLabel.text either A) From inside my timer methods (it says tableView undeclared) and B) In a way that refreshes the cell repeatedly so the user sees an "active" timer.</p> <p>So, here's some code (all of this is in RootViewController right now. Eventually I'll want to make separate classes for functions like the timer, but I just want to get things working first).</p> <p>I should also add that I've got a lot of global ("interface?") variables in this class right now. It makes it easier to experiment, but if that could be causing some of the problems please let me know. I'm still learning how to pass objects/variables/etc back and forth.</p> <pre><code>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; self.runTimerFunctions; } </code></pre> <p>Then the timer function (those are interface variables):</p> <pre><code>- (void) runTimerFunctions { start = CFAbsoluteTimeGetCurrent(); timerRunning = YES; timer = [NSTimer scheduledTimerWithTimeInterval: 0.01 target:self selector:@selector(targetMethod:) userInfo:nil repeats:YES]; } </code></pre> <p>The math and calculation itself. Results in a single string "liveTimer" of the format MM:SS.hh that accurately "stopwatches" upward:</p> <pre><code>- (void)targetMethod: (NSTimer *)theTimer { // NOTE TO SELF -- right now I've got hours, minutes, seconds, etc as global variables. But that may be unnecessary. CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); CFAbsoluteTime timeDelta = end-start; int integerSecs = timeDelta; int integerCentiSecs = timeDelta * 100; hundredths = integerCentiSecs % 100; NSString *hundredthsString = [NSString stringWithFormat:@"%02i", hundredths]; seconds = integerSecs % 60; NSString *secondsString = [NSString stringWithFormat:@"%02i", seconds]; minutes = (integerSecs / 60) % 60; NSString *minutesString = [NSString stringWithFormat:@"%02i", minutes]; // Now combine these value strings into the single liveTimer string liveTimer = [NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString]; } </code></pre> <p>Okay, so the liveTimer string is an interface variable so I can modify it and access it throughout (this may not be the way to do this, again I'm a noob so please correct me wherever necessary).</p> <p>In the initial UITableViewCell creation bit, I use liveTimer for the detail text value, as follows:</p> <pre><code>cell.textLabel.text = @"Name"; NSLog(@"liveTimer value is %@", liveTimer); cell.detailTextLabel.text = liveTimer; </code></pre> <p>So essentially, the way I have things right now, when the user presses the list item, the timer starts counting <em>in the background</em> (I've confirmed with NSLog that it's working correctly -- if I extract liveTimer at the end of targetMethod it's correctly formatted and counting upward.</p> <p>But how do I reflect this via a pseudo real-time update of the cell text?</p> <p>[tableView reloadData] keeps crashing the program (without error code) when I put it anywhere I can, but I don't know how to access it from targetMethod (it tells me tableView undeclared when I add [tableView reloadData] ).</p> <p>Further, [tableView reloadData] keeps crashing the program (without error message) even when I try to drop it experimentally into, say, didSelectRowAtIndexPath. e.g.</p> <pre><code>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; self.runTimerFunctions; [tableView reloadData]; </code></pre> <p>Essentially I'm sure there's a simple way to do what I'm trying to do, but I'm still too new to the language to know how to do it. I wouldn't be surprised if I'm overloading the system by trying to call reloadData during the timer loop. But then again, maybe it's something else.</p> <p>Any advice would be much appreciated. I'm trying to learn the language here so, although sample code is extremely helpful, I'm equally interested in "learning how to fish", so I'd really appreciate explanations of <em>why</em> what I'm doing is wrong and what the better ways to do it might be, etc.</p> <p>Thanks in advance for all your help; I'm looking forward to getting involved on the forums.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload