2013-07-06 3 views
0

Итак, у меня есть таймер, который получает NSTimeInterval от задачи, которую вводит пользователь. Таймер использует класс NSDateComponents для разделения интервала времени в формате HH:MM:SS. По какой-то причине мой ярлык (который имеет формат HH:MM:SS) не обновляется каждый раз, когда отправляется селектор таймера. Я знаю, что селектор работает, потому что каждую секунду отправляется сообщение NSLog, но метка не обновляется. Любые идеи почему?Таймер, не считающийся правильно

TimerViewController.h

@interface DetailViewController : UIViewController{ 
    NSCalendar *gregorianCalendar; 
    NSDateComponents *components; 
} 
@property (weak, nonatomic) IBOutlet UILabel *timeLeft; 
@property (weak, nonatomic) IBOutlet UILabel *timerLabel; 
@property (nonatomic, strong) Tasks *testTask; 
@property NSTimer *timer; 
@property (strong, nonatomic) NSDate *now; 
@property (strong, nonatomic) NSDate *date1; 
-(void)timerAction:(NSTimer *)t; 
@end 

TimerViewController.m

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; 
    [timer fire]; 
    self.date1 = [NSDate dateWithTimeInterval:[testTask timeInterval] sinceDate:[NSDate date]]; 
} 
-(void)timerAction:(NSTimer *)t{ 
    NSDateFormatter *timerFormatter = [[NSDateFormatter alloc]init]; 
    [timerFormatter setDateFormat:@"hh:mm:ss"]; 
    NSDate *now = [NSDate date]; 
    components = [gregorianCalendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:now toDate:self.date1 options:0]; 

    NSString *timeRemaining = nil; 
    if([now compare:self.date1] == NSOrderedAscending){ 
     timeRemaining = [NSString stringWithFormat:@"%02d:%02d:%02d", [components hour], [components minute], [components second]]; 
     NSLog(@"works %@", timeRemaining); 
    } else { 
     timeRemaining = [NSString stringWithFormat:@"00:00:00"]; 
     [timer invalidate]; 
     timer = nil; 
     NSLog(@"ended"); 
    } 
    timerLabel.text = timeRemaining; 
    [timerLabel setNeedsDisplay]; 
    [self.view setNeedsDisplay]; 
} 

Сообщение об ошибке:

*** -[__NSCFCalendar components:fromDate:toDate:options:]: toDate cannot be nil 
I mean really, what do you think that operation is supposed to mean with a nil toDate? 
An exception has been avoided for now. 
A few of these errors are going to be reported with this complaint, then further violations will simply silently do whatever random thing results from the nil. 
Here is the backtrace where this occurred this time (some frames may be missing due to compiler optimizations): 
(
    0 CoreFoundation      0x015bdc78 -[__NSCFCalendar components:fromDate:toDate:options:] + 200 
    1 ToDoTasks       0x0000980b -[DetailViewController timerAction:] + 299 
    2 CoreFoundation      0x0160bff6 -[__NSCFTimer fire] + 150 
    3 ToDoTasks       0x00009393 -[DetailViewController viewDidLoad] + 435 
    4 UIKit        0x002e11c7 -[UIViewController loadViewIfRequired] + 536 
    5 UIKit        0x002e1232 -[UIViewController view] + 33 
    6 UIKit        0x002e14da -[UIViewController contentScrollView] + 36 
    7 UIKit        0x002f88e5 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 36 
    8 UIKit        0x002f89cb -[UINavigationController _layoutViewController:] + 43 
    9 UIKit        0x002f8c76 -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 254 
    10 UIKit        0x002f8d71 -[UINavigationController _startTransition:fromViewController:toViewController:] + 72 
    11 UIKit        0x002f989b -[UINavigationController _startDeferredTransitionIfNeeded:] + 386 
    12 UIKit        0x002f9e93 -[UINavigationController pushViewController:transition:forceImmediate:] + 1030 
    13 UIKit        0x002f9a88 -[UINavigationController pushViewController:animated:] + 62 
    14 ToDoTasks       0x00006acf -[ToDoTableViewController tableView:didSelectRowAtIndexPath:] + 1567 
    15 UIKit        0x002af285 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1194 
    16 UIKit        0x002af4ed -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 201 
    17 Foundation       0x00cb95b3 __NSFireDelayedPerform + 380 
    18 CoreFoundation      0x0156d376 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22 
    19 CoreFoundation      0x0156ce06 __CFRunLoopDoTimer + 534 
    20 CoreFoundation      0x01554a82 __CFRunLoopRun + 1810 
    21 CoreFoundation      0x01553f44 CFRunLoopRunSpecific + 276 
    22 CoreFoundation      0x01553e1b CFRunLoopRunInMode + 123 
    23 GraphicsServices     0x0260f7e3 GSEventRunModal + 88 
    24 GraphicsServices     0x0260f668 GSEventRun + 104 
    25 UIKit        0x001ffffc UIApplicationMain + 1211 
    26 ToDoTasks       0x00001fad main + 141 
    27 ToDoTasks       0x00001ed5 start + 53 
) 
2013-07-05 18:00:51.452 ToDoTasks[30968:c07] ended 
+0

Попробуйте вывести 'timeRemaining' (' NSLog (@ "таймер работает% @", timeRemaining); '). Я предполагаю, что разница во времени просто не меняется. – Danilo

+0

О, хватит, ты прав. что мне тогда делать? – EvilAegis

+0

см. Мой ответ ниже – Danilo

ответ

1

Сделать date1 свойство и сделать

self.date1 = [NSDate dateWithTimeInterval:[testTask timeInterval] sinceDate:now]; 

внутри viewDidLoad. Таким образом, ваша разница во времени фактически уменьшится.

Редактировать снизу:

Не делайте now дату метод собственности, положил его обратно в timerAction с первого редактирования.

Edit2:

изменить ваш рабочий процесс в viewDidLoad. Первый набор self.date1, затем расписание таймера.

+0

У меня есть самая странная ошибка. Похоже, что Apple насмехается над LOL: »- [__ Компоненты NSCFCalendar: fromDate: toDate: options:]: toDate не может быть nil Я имею в виду, действительно, как вы думаете, что операция должна означать с нулем toDate? Исключение было исключено на данный момент Некоторые из этих ошибок будут сообщены с этой жалобой, а затем дальнейшие нарушения просто молчат независимо от того, какая случайная вещь получается из нуля. Вот обратная трасса, где это произошло на этот раз (некоторые фреймы может отсутствовать из-за оптимизации компилятора): « – EvilAegis

+0

Это означает, что ваш' toDate' был 'nil'. Вы сделали 'date1' слабым свойством? – Danilo

+0

Я только что сделал и получил ту же ошибку T_T, кроме «FromDate» – EvilAegis

1

Вы должны сделать вид перерисовки обновить значение

Как это:

[self.superview setNeedsDisplay]; 

Проверьте это: Redrawing a view in ios

Итак, ваша проблема в том, что интервал времени не меняя, используйте это:

С чего начать Сохранить дату:

NSDate *then = [NSDate now];//gives you the current time 

Когда действие выполняется сохранить следующую дату:

NSDate *now = [NSDate now]; 

Затем получить интервал времени:

NSTimeInterval secondsBetween = [now timeIntervalSinceDate:then]; 
+0

hmm ... superview недействителен в моем контролере зрения, поэтому я положил это: '[self.посмотреть setNeedsDisplay], в моем селекторе таймера ' сразу после ' timerLabel.text = timeRemaining; ' , но все-таки получили никаких результатов .. – EvilAegis

+0

попробуйте сделать timerLabel.text = timeRemaining; [timerLabel setNeedsDisplay]; и затем [self.view setNeedsDisplay]; это работает? – jsedano

+0

Странно, но должно быть правильно – EvilAegis