1

Okay. If you have two viewControllers and you do a modal Segue from the first to the second, then you dismiss it with [self dismissModalViewControllerAnimated:YES]; it doesn't seem to recall viewDidLoad. I have a main page (viewController), then a options page of sorts and I want the main page to update when you change an option. This worked when I just did a two modal segues (one going forward, one going back), but that seemed unstructured and may lead to messy code in larger projects.

I have heard of push segues. Are they any better?

Thanks. I appreciate any help :).

Greg Cawthorne
  • 396
  • 5
  • 21

1 Answers1

10

That's because the UIViewController is already loaded in memory. You can however use viewDidAppear:.

Alternatively, you can make the pushing view controller a delegate of the pushed view controller, and notify it of the updates when the pushed controller is exiting the screen.

The latter method has the benefit of not needing to re-run the entire body of viewDidAppear:. If you're only updating a table row, for example, why re-render the whole thing?

EDIT: Just for you, here is a quick example of using delegates:

#import <Foundation/Foundation.h>

// this would be in your ModalView Controller's .h
@class ModalView;

@protocol ModalViewDelegate

- (void)modalViewSaveButtonWasTapped:(ModalView *)modalView;

@end

@interface ModalView : NSObject

@property (nonatomic, retain) id delegate;

@end

// this is in your ModalView Controller's .m
@implementation ModalView

@synthesize delegate;

- (void)didTapSaveButton
{
    NSLog(@"Saving data, alerting delegate, maybe");

    if( self.delegate && [self.delegate respondsToSelector:@selector(modalViewSaveButtonWasTapped:)])
    {
        NSLog(@"Indeed alerting delegate");

        [self.delegate modalViewSaveButtonWasTapped:self];
    }
}

@end

// this would be your pushing View Controller's .h
@interface ViewController : NSObject <ModalViewDelegate>

- (void)prepareForSegue;

@end;

// this would be your pushing View Controller's .m
@implementation ViewController

- (void)prepareForSegue
{
    ModalView *v = [[ModalView alloc] init];

    // note we tell the pushed view that the pushing view is the delegate
    v.delegate = self;

    // push it

    // this would be called by the UI
    [v didTapSaveButton];
}

- (void)modalViewSaveButtonWasTapped:(ModalView *)modalView
{
    NSLog(@"In the delegate method");
}

@end

int main(int argc, char *argv[]) {
    @autoreleasepool {

        ViewController *v = [[ViewController alloc] init];

        [v prepareForSegue];
    }
}

Outputs:

2012-08-30 10:55:42.061 Untitled[2239:707] Saving data, alerting delegate, maybe
2012-08-30 10:55:42.064 Untitled[2239:707] Indeed alerting delegate
2012-08-30 10:55:42.064 Untitled[2239:707] In the delegate method

Example was ran in CodeRunner for OS X, whom I have zero affiliation with.

Josh
  • 12,448
  • 10
  • 74
  • 118
  • 1
    Thanks! That's exactly what I needed :). Would there be a way of identifying which viewController it had come from? Also, will the viewDidAppear method execute on launch? If so could I basically empty the viewDidLoad method and put it's contents in the viewDidAppear method? Is there a chance of the viewController being deleted by the garbage collector? Meaning that it would in fact have to execute the viewDidLoad method. If that happened would the viewDidAppear method still execute? Sorry for spamming these at you :P. I just want to learn :) – Greg Cawthorne Aug 30 '12 at 15:55
  • 1
    @GregCawthorne: Well, if you add `self` as the ModalView's delegate as you're pushing it, you have a pointer to the pushing View Controller. And it depends on what you're doing in `viewDidLoad`. You'll not want to move things that only happen once into `viewDidAppear`, as it can be called 1+ times. Things like member initialization should stay in `viewDidLoad`. And, if you use a delegate, which lots of Apple sample code is now using, you can just leave it all in `viewDidLoad`, and update the corresponding parts in the implemented protocol method. – Josh Aug 30 '12 at 15:58
  • Thanks a lot. I am new to iPhone programming and the idea of delegates. There are a few things I'm a tad unsure about. In the if statement in the 'didTapSaveButton' method, what would 'self.delegate' return? By the looks of it you have assigned it the value self, which is basically a viewController reference, how does that equate to a true or false statement for the if condition? And what is a selector? Does this '[self.delegate respondsToSelector:@selector(modalViewSaveButtonWasTapped:]', basically mean: 'If the method 'modalViewDaveButtonWasTapped' is in self.delegate' return true? – Greg Cawthorne Aug 30 '12 at 16:16
  • Finally it seems you have declared a method 'prepareForSegue' in a .h file? In my experience you declare outlets/action in .h files and methods in .m files? – Greg Cawthorne Aug 30 '12 at 16:17
  • 1
    @GregCawthorne: Firstly, when you initialize a class, all of it's pointers are set to `nil` (something like 0x00000000). The `if( self.delegate )` will return false if `self.delegate` is nil. Therefore, we make sure there is a delegate. Secondly, you can send any message to `nil` or an object, and it won't check until runtime. Therefore, adding that check circumvents some common crash cases - nil pointers and no target receivers. – Josh Aug 30 '12 at 16:18
  • 1
    @GregCawthorne: If you decide to go with Segues, that method is automatically called by the Obj-C runtime before it loads up the next ViewController. I only put it in the .h so that when we call it in main(), it doesn't throw an error that "v may not respond to selector", which I mentioned above. As with any C like language, to be the most safe, you'll want to expose your public method signatures in your interface. – Josh Aug 30 '12 at 16:20
  • 1
    @GregCawthorne: It sounds like you're not quite up to speed on some fundamental Objective-C things, so I'd highly recommend that you read [this guide](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html) before you mess around with iOS. – Josh Aug 30 '12 at 16:24
  • 1
    I will definitely read up on that guide. I have taken the 'experiment and see' approach to this so far and have gotten a few apps together, but don't feel I have a thorough understand of the system yet. Thank you :). – Greg Cawthorne Aug 30 '12 at 16:39
  • @GregCawthorne: I learned the same way, and in retrospect, it was more painful than it needed to be. Just keep going through the Apple docs / tutorials, and you'll be in great shape in no time. – Josh Aug 30 '12 at 16:40
  • @GregCawthorne. Is it fine to call viewWillAppear multiple times ? – Avijit Nagare Apr 07 '16 at 08:22
  • @Josh.Is it fine to call viewWillAppear multiple times ? – Avijit Nagare Apr 07 '16 at 08:23