0

I'm creating a countdown and want to display the countdown time as well as the unit names (years, months, days, hours, minutes, seconds) under the countdown label at the appropriate position. I have a UILabel object called countdownLabel which I put into a UIView subview using the story board. The size of the countdownLabel spans the width of the subView it's in and leaves a little room for the time unit labels that I want to add.

I have a NSTimer that calls the updateLabel method to update the countdownLabel

- (void)updateLabel
{
    NSString *counterStr;

    self.dateComponents = [self.gregorianCalendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit)
                                                    fromDate:[NSDate date]
                                                      toDate:self.countdownDate
                                                     options:0];

    int yearsRemaining   = [self.dateComponents year];
    int monthsRemaining  = [self.dateComponents month];
    int daysRemaining    = [self.dateComponents day];
    int hoursRemaining   = [self.dateComponents hour];
    int minutesReamining = [self.dateComponents minute];
    int secondsReamining = [self.dateComponents second];

    if ((yearsRemaining + monthsRemaining + hoursRemaining + minutesReamining + secondsReamining) > 0)
    {
        if (yearsRemaining == 0 && monthsRemaining == 0 && daysRemaining == 0 && hoursRemaining == 0)
            counterStr = [NSString stringWithFormat:@"%02d:%02d", minutesReamining, secondsReamining];

        else if (yearsRemaining == 0 && monthsRemaining == 0 && daysRemaining == 0)
            counterStr = [NSString stringWithFormat:@"%02d:%02d:%02d", hoursRemaining, minutesReamining, secondsReamining];

        else if (yearsRemaining == 0 && monthsRemaining == 0)
            counterStr = [NSString stringWithFormat:@"%02d:%02d:%02d:%02d", daysRemaining, hoursRemaining, minutesReamining, secondsReamining];

        else if (yearsRemaining == 0)
            counterStr = [NSString stringWithFormat:@"%02d:%02d:%02d:%02d:%02d", monthsRemaining, daysRemaining, hoursRemaining, minutesReamining, secondsReamining];

        else
            counterStr = [NSString stringWithFormat:@"%i:%02d:%02d:%02d:%02d:%02d", yearsRemaining, monthsRemaining, daysRemaining, hoursRemaining, minutesReamining, secondsReamining];

    }
    else
        counterStr = @"Countdown Ended!";

    self.countdownLabel.text = counterStr;

}

The timer aspect of the app works just fine. However, I can't seem to figure out how to add the time unit labels at run time so that I only add the labels I need based on whats shown in the countdown label and have the time unit labels align under the respective time below the countdown label.

I've tried using a method that extracted the respective time value as a substring and then figured out where to put the the time unit label based on that substring rect, but it didn't work well or look pretty.

There has to be an easier way to do this and I'm just learning Objective C so any help would be much appreciated!

Community
  • 1
  • 1
Dmitry K.
  • 972
  • 6
  • 16
  • You're going to have issues using 2 separate `UILabel`s for each row (unless you use a fixed width font). You'd be better off having a `UILabel` for each unit label and each value label. Then you could align the value label below its respective unit label. – Rich Apr 29 '14 at 21:38
  • I couldn't figure out how to do this dynamically and keep everything centered. I don't want to add a 6 labels for the time and 6 labels for the unit names to the story board because I want the text to be larger depending on how much time is left. I can add labels to the subview and if it's only one, I can get it centered. However when I add a second label or more, I don't know how to keep them all centered relative to each other and the subview. – Dmitry K. Apr 29 '14 at 21:41
  • Are you using (or have used) AutoLayout? You would have to leave a container in Interface Builder (to save working out how/where to place it) and then like you said, dynamically add the labels. AutoLayout would take care of the spacing and sizing. How often is `updateLabel` called? The only issue is if its called less than every second you'd have to refactor your code to an update time method and a setup labels method. – Rich Apr 29 '14 at 21:45
  • updateLabel is currently called every second but I can lower that if needed. I have tried using AutoLayout, and I can do simple things with it but I am not that great with it. Would I have to create 12 UILabels (6 for the times and 6 for the unit labels) to determine where everything should go? – Dmitry K. Apr 29 '14 at 21:50
  • Yeah! It wouldn't be the simplest and nicest bit of code - layout code never is. Or the other option would be 1 `UILabel` for unit and value, but force a line break in the label and then centre it. It would then give it the appearance of being on top of each other. – Rich Apr 29 '14 at 21:53
  • Hmm ok I will try that. I'm also using a PageViewController. Feel free to tell me this idea is terrible programming, but what if I created a separate ContentView each with a unique story board ID and then based on how many time units are needed, I could dynamically just pull the one I need into the PageViewController? – Dmitry K. Apr 29 '14 at 21:56
  • I don't use Storyboards I'm afraid so I don't want to go giving you useless/bad advice, sorry! – Rich Apr 29 '14 at 22:01
  • Oh though I do think I understand what you mean, you'd have 6 storyboards? One for each layout? – Rich Apr 29 '14 at 22:02
  • Yeah basically I would add 6 View Controllers to the story board, and just setup the countdownLabel on each one. Seems like it would most be a quick copy and paste job. – Dmitry K. Apr 29 '14 at 22:04
  • It seems like it would work! I'd at least subclass `UILabel` for both the units and values, so if you want to change their style, you only need to do it in one place, and not `(6+5+4+3+2)*2` times in Interface Builder! If that makes sense. – Rich Apr 29 '14 at 22:08

0 Answers0