7

When the user start the app I want it show the stockholm.xib and It does here:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    NSUserDefaults *startPage =[NSUserDefaults standardUserDefaults];
    NSString *page =[startPage stringForKey:@"page"];
    NSLog(page);

    if(page==nil)
    {
        //Do nothing

    }
    else if ([page isEqualToString:@"Default"])
    {
        //Do nothing
    }

    else if ([page isEqualToString:@"Stockholm"])
    {
        NSLog(@"going to Stockholm");
        Stockholm *Start =[[Stockholm alloc]initWithNibName:nil bundle:nil];
        [self presentModalViewController:Start animated:YES];


    }
    else {
        NSLog(@"HAHA");

}

but when user closes the stockholm.xib using:

[self dismissModalViewControllerAnimated:YES];

after the animation is done, the app crashes. and the reason is, I guess, viewDidAppear calls twice and therefore it is trying to open the recently closed xib file.

now, how Can I call the view did appear only once? so that when the user comes back from Stockholm the viewDidAppear wont be called? any other solution?

thanx :)

hafhadg3
  • 626
  • 2
  • 7
  • 15

3 Answers3

14

You can try moving all that functionality in the viewDidLoad: method instead of the viewDidAppear. That one only fires once. Unless there is a reason for you not to...?

EDIT: more code to show what i mean in the comment

in the .h file:

BOOL firstTime;

in the .m file:

-(void)viewDidLoad {
   NSLog(@"viewDidLoad actually fired");
   //...
   firstTime = YES;
}
-(void)viewDidAppear {
   //...
   if(firstTime){
      //show it
      firstTime = NO;
   }
}
Dimitris
  • 12,954
  • 17
  • 71
  • 93
  • yes, the reason is that If I move this: Stockholm *Start =[[Stockholm alloc]initWithNibName:nil bundle:nil]; [self presentModalViewController:Start animated:YES]; to viewdidLoad, it wont work. – hafhadg3 Feb 14 '10 at 12:48
  • 1
    If you only want to show it the first time the view appears, just use a boolean flag to tell if it is the first time or not. BOOL firstTime = true; if(... && firstTime) { firstTime = false; ...} – Dimitris Feb 14 '10 at 13:17
  • It still doesnt work. .h static BOOL firstTime=TRUE; .m -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; if (firstTime=TRUE) { //Go to the custom Page } firstTime=FALSE; } i get this error: 0x018ce464 jne 0x18ce481 please HELP! – hafhadg3 Feb 17 '10 at 21:37
6

You can use GCD, too, if your class has a field such as:

@interface MyClass {
    dispatch_once_t once;
}

@end

@interface MyClass {
    - (void)viewDidAppear:(BOOL)animated {
        dispatch_once(&once, ^{
            // do business
        });
    }
@end
ZaBlanc
  • 4,631
  • 1
  • 32
  • 37
  • 2
    EDIT: Still need the flag. Using a method static would mean the code would run just once no matter how many instances of the view controller were created. – ZaBlanc Feb 19 '12 at 03:40
  • This is _seems_ like a good idea, but it will actually result in undefined behavior: `The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage is undefined.` – datwelk Dec 08 '13 at 13:08
1

You can add the property like BOOL loaded to your viewcontroller, set it to false in the viewdidload, and then make your viewDidAppear method like:

- (void)viewDidAppear:(BOOL)animated {
    if (!loaded) {
        //code
    } else {
        return;
    }
    loaded = YES;
}

That works for me.

Frane Poljak
  • 2,137
  • 19
  • 21