Таймер обратного отсчета: обновление меток вида контроллера

#ios #datepicker #uilabel #nstimer #viewcontroller

#iOS #выбор даты #uilabel #nstimer #viewcontroller

Вопрос:

Я пытаюсь настроить таймер обратного отсчета. У меня есть два контроллера просмотра: ViewController и EditViewController. ViewController имеет две метки: часы и минуты. В EditViewController есть UIDatePicker и кнопка сохранения. Когда пользователь выбирает время в UIDatePicker и нажимает сохранить, они перенаправляются обратно в ViewController, а метки часов и минут заполняются разницей между выбранным временем и текущим временем. Это значение автоматически обновляется до тех пор, пока разница не станет равной 0. У меня возникли проблемы при попытке корректно отобразить часы и минуты на метках ViewController. Вот мой код:

ViewController.m

 @interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.hourLabel.text = self.hourText;
    self.minuteLabel.text = self.minuteText;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
  

Отредактируйте ViewController.h

 @interface EditViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIDatePicker *datePicker;
@property (weak, nonatomic) IBOutlet NSString *currentTimeString;
@property (weak, nonatomic) IBOutlet NSString *endTimeString;
- (IBAction)saveButton:(id)sender;
- (IBAction)cancelButton:(id)sender;

-(void)updateTime;

@end
  

Отредактируйте ViewController.m

 #import "EditViewController.h"
#import "ViewController.h"

@interface EditViewController ()

@end

@implementation EditViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)saveButton:(id)sender
{

    NSCalendar *now = [NSCalendar autoupdatingCurrentCalendar];
    NSInteger currentTime = (NSHourCalendarUnit | NSSecondCalendarUnit);
    self.datePicker.date = [now dateFromComponents:[now components:currentTime fromDate:self.datePicker.date]];

    NSTimer *timer;
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];

    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)updateTime
{
    NSInteger timeLeft = ((NSInteger)[self.datePicker.date timeIntervalSinceNow]);
    NSInteger minutes = (timeLeft / 60) % 60;
    NSInteger hours = (timeLeft / 3600) % 24;

    ViewController *controller;
    controller.hourText = [NSString stringWithFormat:@"%ldi",(long)hours];
    controller.minuteText = [NSString stringWithFormat:@"%ldi",(long)minutes];
    NSLog(@"The time is %ld",(long)timeLeft);

}

- (IBAction)cancelButton:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
  

Любая помощь приветствуется. Заранее спасибо.

Ответ №1:

Посмотрите здесь отредактированный метод из вашего кода. Это полностью удовлетворит вашим требованиям.

 #import "EditViewController.h"
#import "ViewController.h"
#import "AppDelegate.h"
@interface EditViewController ()
{
    AppDelegate *appDelegate;
}
@end

@implementation EditViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        // Custom initialization
        appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    }
    return self;
}


-(void)updateTime
{
    NSInteger timeLeft = ((NSInteger)[self.datePicker.date timeIntervalSinceNow]);
    NSInteger minutes = (timeLeft / 60) % 60;
    NSInteger hours = (timeLeft / 3600) % 24;

    NSString *hourText = [NSString stringWithFormat:@"%ldi",(long)hours];
    NSString *minuteText = [NSString stringWithFormat:@"%ldi",(long)minutes];

    [appDelegate updateTime:hourText andMinute:minuteText];

}
  

и, наконец, определите метод в классе AppDelegate

 - (void) updateTime:(NSString *)hourStr andMinute:(NSString *)minuteStr
{
   for(id obj in [self.navigationController viewControllers])
   {
      if([obj isKindOfClass:ViewController])
      {
        ViewController *vcObj = (ViewController *)obj;
        vcObj.hourLabel.text = hourStr;
        vcObj.minuteLabel.text = minuteStr;

      }
   }
}
  

Ответ №2:

Несколько проблем:

ViewController.m

 self.hourLabel.text = self.hourText;
self.minuteLabel.text = self.minuteText;
  

Должно быть в viewWillAppear вместо viewDidLoad . Происходит то, что вы устанавливаете текст при загрузке приложения. viewDidLoad сработает только один раз для этого экземпляра приложения. Что вам нужно сделать, так это обновить его, когда вы вернетесь из EditViewController, верно? Поэтому, если вы введете его viewWillAppear , он также будет вызван, когда вы вернетесь и обновите его для себя.

Следующее, что:

Отредактируйте ViewController.m

 ViewController *controller;
controller.hourText = [NSString stringWithFormat:@"%ldi",(long)hours];
controller.minuteText = [NSString stringWithFormat:@"%ldi",(long)minutes];
NSLog(@"The time is %ld",(long)timeLeft);
  

В этом фрагменте кода объявляется новая переменная ViewController (ну, по большей части, вы пропускаете = [ViewController new] часть). Проблема в том, что вы ничего не делаете с этим контроллером. ViewController фактически уже находится в вашем навигационном стеке (я предполагаю, что NavigationController, поскольку вы сказали, когда пользователь вернется), поэтому вам нужно использовать ссылку на ViewController, экземпляр которой уже создан вашим приложением, а не создавать новый, поскольку вы никогда нигде не используете этого парня.