rattletrap99
rattletrap99

Reputation: 1479

Updating a UILabel in a UITableViewCell in realtime

Please see edit below

I'm trying to update the text in a label in a UITableViewCell in real time to reflect the elapsed time since the cell was selected via didSelectRowAtIndexPath.

The symptom of the problem is that the label remains blank.

Here is the code in my updateTime method:

-(void)updateTime
{


    //Which calendar
    NSCalendar *calendar = [NSCalendar currentCalendar];

    //Gets the componentized interval from the most recent time an activity was tapped until now
    NSDateComponents *components= [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:currentTimedActivity.startTime toDate:[NSDate date] options:0];

    NSInteger hours = [components hour];
    NSInteger minutes = [components minute];
    NSInteger seconds =[components second];
//    
    if(!seconds)
    {
        [timer invalidate];

    }
    //Converts the components to a string and displays it in the duration label
    cellLabelTempText = [NSString stringWithFormat:@"%02i:%02i:%02i",hours,minutes,seconds];
    self.durationLabel.text = cellLabelTempText;

    NSLog(@"The label should be reading %02i:%02i:%02i",hours,minutes,seconds);
    NSLog(@"cellLabelTempText is reading %@",cellLabelTempText);
    NSLog(@"The durationLabel should read the same, as they are equal.");
    NSLog(@"The durationLabel is actually showing %@",self.durationLabel.text);


    [self.myTableView reloadData];

}

My NSLog instructions yield the following:

2014-03-12 14:48:57.433 WMDGx[69802:a0b] The label should be reading 00:00:00
2014-03-12 14:48:57.434 WMDGx[69802:a0b] cellLabelTempText is reading 00:00:00
2014-03-12 14:48:57.435 WMDGx[69802:a0b] The durationLabel should read the same, as they are equal.
2014-03-12 14:48:57.435 WMDGx[69802:a0b] The durationLabel is actually showing (null)
2014-03-12 14:48:57.933 WMDGx[69802:a0b] The label should be reading 00:00:01
2014-03-12 14:48:57.934 WMDGx[69802:a0b] cellLabelTempText is reading 00:00:01
2014-03-12 14:48:57.934 WMDGx[69802:a0b] The durationLabel should read the same, as they are equal.
2014-03-12 14:48:57.935 WMDGx[69802:a0b] The durationLabel is actually showing (null)
2014-03-12 14:48:58.933 WMDGx[69802:a0b] The label should be reading 00:00:02
2014-03-12 14:48:58.934 WMDGx[69802:a0b] cellLabelTempText is reading 00:00:02
2014-03-12 14:48:58.934 WMDGx[69802:a0b] The durationLabel should read the same, as they are equal.
2014-03-12 14:48:58.935 WMDGx[69802:a0b] The durationLabel is actually showing (null)
2014-03-12 14:48:59.933 WMDGx[69802:a0b] The label should be reading 00:00:03
2014-03-12 14:48:59.934 WMDGx[69802:a0b] cellLabelTempText is reading 00:00:03
2014-03-12 14:48:59.934 WMDGx[69802:a0b] The durationLabel should read the same, as they are equal.
2014-03-12 14:48:59.934 WMDGx[69802:a0b] The durationLabel is actually showing (null)
2014-03-12 14:49:00.933 WMDGx[69802:a0b] The label should be reading 00:00:04
2014-03-12 14:49:00.933 WMDGx[69802:a0b] cellLabelTempText is reading 00:00:04
2014-03-12 14:49:00.934 WMDGx[69802:a0b] The durationLabel should read the same, as they are equal.
2014-03-12 14:49:00.934 WMDGx[69802:a0b] The durationLabel is actually showing (null)

I'm stumped because the temporary string cellLabelTempText is updating correctly, and self.durationLabel.text is equal to cellLabelTempText, yet registers as (null) in the log.

All help much appreciated!

Edit per @rmaddy's suggestion in comments below (please read):

Since my self.durationLabel is showing nil, I tried connecting to an IBOutlet, but get this error:

... /WMDGx/MainStoryboard.storyboard: Couldn't compile connection: <IBCocoaTouchOutletConnection:0x7ff6a28f8560  <IBProxyObject: 0x7ff6a28f55e0> => durationLabel => <IBUILabel: 0x7ff6a28f34a0>>

This gives a good indication about where the problem lies, but if the whole thing depends on an IBOutlet, and I can't hook it up to one, where do I go from here?

Thanks!

Upvotes: 0

Views: 709

Answers (1)

mackworth
mackworth

Reputation: 5953

Your issue is that you don't have a single durationLabel; you have as many as you have cells in your table. (The error specifically is trying to connect a tableCell prototype to a specific label). I'd suggest subclassing UITableviewCell, adding a durationLabel label and property (which can be linked to a prototype cell), and putting this timer code inside that subclass.

Something like this:

In your tableViewController:

//At the top:
#import "PTCell.h"

//replace didSelectRowAtIndexPath:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    PTCell * cell = (PTCell *)[tableView cellForRowAtIndexPath:indexPath];
    [cell startTimer];
}

PTCell.h:

#import <UIKit/UIKit.h>

@interface PTCell : UITableViewCell;
@property (strong, nonatomic) IBOutlet UILabel *durationLabel;
@property (nonatomic, strong) NSDate * startTime;
@property (nonatomic, strong) NSTimer * timer;

-(void) startTimer;
-(void) stopTimer;

@end

PTCell.m:

#import "PTCell.h"

@implementation PTCell

-(void)updateTime {

    //Which calendar
    NSCalendar *calendar = [NSCalendar currentCalendar];

    //Gets the componentized interval from the most recent time an activity was tapped until now
    NSDateComponents *components= [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:self.startTime toDate:[NSDate date] options:0];

    NSInteger hours = [components hour];
    NSInteger minutes = [components minute];
    NSInteger seconds =[components second];
    //
    if(!seconds)
    {
        [self.timer invalidate];

    }
    //Converts the components to a string and displays it in the duration label
    NSString * cellLabelTempText = [NSString stringWithFormat:@"%02i:%02i:%02i",hours,minutes,seconds];
    self.durationLabel.text = cellLabelTempText;

    NSLog(@"The label should be reading %02i:%02i:%02i",hours,minutes,seconds);
    NSLog(@"cellLabelTempText is reading %@",cellLabelTempText);
    NSLog(@"The durationLabel should read the same, as they are equal.");
    NSLog(@"The durationLabel is actually showing %@",self.durationLabel.text);

}

-(void) startTimer {
    [self stopTimer];
    self.startTime = [NSDate date];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
}

-(void) stopTimer {
    [self.timer invalidate];
    self.timer = nil;
}

@end

Upvotes: 2

Related Questions