如何从主应用程序委托访问viewcontroller属性?

时间:2013-01-09 22:09:05

标签: objective-c delegates controller refresh xcode4.5

我的项目是一个带有tabbarcontroller和3个viewcontrollers的窗口。第一个viewcontroller有一个datepicker。我使用当前日期([NSDate date])作为选择器的最大限制。

问题在于我无法使用较新的日期刷新该选择器(例如,假设我在几天之后运行该应用程序)。

在研究了这个论坛后,我发现我必须在此方法中进行刷新(在委托文件中):- (void)applicationDidBecomeActive:(UIApplication *)application

但我无法从那里创建对第一个视图控制器的正确引用。 我试图使用指向[self.window.rootViewController.tabBarController.viewControllers objectAtIndex:0]的指针,但似乎它没有指向视图控制器。

有人对此问题有任何想法吗?

以下是代码:

//
//  PNAppDelegate.m
//

#import "PNAppDelegate.h"
#import "PPPViewController.h"
#import "IGPreviaViewController.h"
#import "IGUsgViewController.h"


@implementation PNAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];


    PPPViewController *pppvc = [[PPPViewController alloc] init];


    IGPreviaViewController *igpvc = [[IGPreviaViewController alloc] init];


    IGUsgViewController *iguvc = [[IGUsgViewController alloc] init];

    UITabBarController *tabBarController = [[UITabBarController alloc] init];
    NSArray *viewControllers = [NSArray arrayWithObjects:pppvc, igpvc, iguvc, nil];
    [tabBarController setViewControllers:viewControllers];

    [[self window] setRootViewController:tabBarController];


    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}


- (void)applicationDidBecomeActive:(UIApplication *)application
{





    PPPViewController *pppvc = [self.window.rootViewController.tabBarController.viewControllers objectAtIndex:0];

    [pppvc.dumPicker setMaximumDate:[NSDate date]];


   // Here I don't know how to proceed in order to refresh the picker in the first viewcontroller




}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end



//
//  PPPViewController.m
//


#import "PPPViewController.h"
#import "IdadeGestacional.h"


@implementation PPPViewController

@synthesize dumPicker,idadeGest,dataParto,periodoParto,dum;

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        UITabBarItem *tbi = [self tabBarItem];
        [tbi setTitle:@"IG/DPP"];

        UIImage *i = [UIImage imageNamed:@"calendario.png"];

        // Put that image on the tab bar item
        [tbi setImage:i];

    }
    return self;
}

-(void)viewDidLoad
{
    [super viewDidLoad];

   // cria o dumPicker

    dum = [self acertaData:[NSDate date]];

    dumPicker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 80, 0, 0)];
    [dumPicker setTransform:CGAffineTransformMakeScale(0.8, 0.8)];
    [dumPicker setDatePickerMode:UIDatePickerModeDate];
    [dumPicker setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"pt_BR"]];

    [dumPicker setMaximumDate:[NSDate date]];

    NSDate *minDate = [[NSDate alloc] initWithTimeInterval:(-300*24*60*60) sinceDate:[NSDate date]];
    [dumPicker setMinimumDate:minDate];
    [dumPicker addTarget:self action:@selector(changeDum) forControlEvents:UIControlEventValueChanged];

    [self.view addSubview:dumPicker];




    [idadeGest setText:@""];
    [dataParto setText:@""];
    [periodoParto setText:@""];

}


-(void)changeDum
{    

   // Define a DUM (data inicial)
    NSDate *dataInicial = [[NSDate alloc]init];

    if ([[NSTimeZone localTimeZone] isDaylightSavingTime]) {
        dataInicial = [[dumPicker date] dateByAddingTimeInterval:(60*60)];
    }
    else {
        dataInicial = [dumPicker date];
    };


    dum = [self acertaData:dataInicial];





    // Calcula a IG
    IdadeGestacional *IG = [[IdadeGestacional alloc] initWithDataInicial:dum dataFinal:[self acertaData:[NSDate date]]];
    [IG calculaIG];
    [IG display];


    // Mostra a IG
    NSString *IGLabel = @"";
    if (IG.semanas)
    {
        if (IG.dias)
            IGLabel = [NSString stringWithFormat:@"%ds%dd",IG.semanas,IG.dias];
        else IGLabel = [NSString stringWithFormat:@"%ds",IG.semanas];
    } else if (IG.dias) IGLabel = [NSString stringWithFormat:@"%dd",IG.dias];


    [idadeGest setText:IGLabel];

    // Calcula a DPP
    NSDate *dpp = [[NSDate alloc] initWithTimeInterval:(280*24*60*60) sinceDate:dataInicial];

    // Mostra a DPP
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"dd/MM/yyyy"];

    [dataParto setText:[df stringFromDate:dpp]];

    // Calcula o PPP
    NSDate *pppi = [[NSDate alloc] initWithTimeInterval:(266*24*60*60) sinceDate:dataInicial];
    NSDate *pppf = [[NSDate alloc] initWithTimeInterval:(294*24*60*60) sinceDate:dataInicial];

    // Mostra o PPP
    NSString *PPParto = [NSString stringWithFormat:@"%@ a %@",[df stringFromDate:pppi],[df stringFromDate:pppf]];
    [periodoParto setText:PPParto];

}

-(NSDate *)acertaData:(NSDate *)dataBruta
{


    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit ;


    NSDateComponents *comps = [[NSCalendar currentCalendar] components:unitFlags fromDate:dataBruta];

    NSDate *novaData = [[NSCalendar currentCalendar] dateFromComponents:comps];

    [self mostraData:novaData];

    return novaData;
}

-(void)mostraData:(NSDate *)dataBruta
{
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit | NSCalendarCalendarUnit;
    NSDateComponents *comps = [[NSCalendar currentCalendar] components:unitFlags fromDate:dataBruta];

    NSLog(@"nova data");
    NSLog(@"%d %d %d %d %d %d %@ %@",comps.year,comps.month,comps.day,comps.hour,comps.minute,comps.second,comps.timeZone.abbreviation,comps.calendar.calendarIdentifier);
    NSLog(@"%@",comps.timeZone.name);
}

@end

2 个答案:

答案 0 :(得分:2)

为什么要在应用程序委托中而不是在视图控制器中执行此操作? AppDelegate负责应用程序范围的任务(因此它使用的委托方法)。如果需要刷新视图控制器内部的视图,请在视图控制器中执行 - 这是MVC设计模式的重点。

如果是UITabBarController,我会在viewWillAppear进行此次更新。在此方法中,您可以更新maximumDate属性的值。

更新:如果在重新启动应用时似乎没有调用viewWillAppear:viewDidAppear:,您可以在视图控制器内订阅AppDelegate通知。 Apple的代表团范式遵循一项政策,即他们倾向于广播与委托方法相匹配的通知。例证:有一个名为UIApplicationDidBecomeActiveNotification的NSNotification。您可以在viewWillAppear:中订阅此通知:

- (void)viewWillAppear:(BOOL)animated {
   [super viewWillAppear:animated];
   [[NSNotificationCenter defaultCenter] addObserver:self 
                                            selector:@selector(applicationDidBecomeActive:) 
                                                name:UIApplicationDidBecomeActiveNotification 
                                              object:nil];
}

- (void)applicationDidBecomeActive:(NSNotification *)note {
   self.datePicker.maximumDate = [NSDate date];
}

请务必在viewWillDisappear:

中删除此观察者

答案 1 :(得分:-1)

在PPPViewController标头和实现文件中,创建一个名为的方法 - (void)refreshPicker;

在此方法的实现中,将dumPicker的maximumDate设置为:

- (void)refreshPicker
{
    [self.dumPicker setMaximumDate:[NSDate date]];
}

使用通知。在applicationDidBecomeActive方法中,您可以调用

[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshPicker" object:nil];

并且在PPPViewController的viewDidLoad方法中,您可以通过在以下位置添加以下代码来添加观察者:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPicker) object:nil];