Looking to Understand the iOS Uiviewcontroller Lifecycle

Looking to understand the iOS UIViewController lifecycle

All these commands are called automatically at the appropriate times by iOS when you load/present/hide the view controller. It's important to note that these methods are attached to UIViewController and not to UIViews themselves. You won't get any of these features just using a UIView.

There's great documentation on Apple's site here. Putting in simply though:

  • ViewDidLoad - Called when you create the class and load from xib. Great for initial setup and one-time-only work.

  • ViewWillAppear - Called right before your view appears, good for hiding/showing fields or any operations that you want to happen every time before the view is visible. Because you might be going back and forth between views, this will be called every time your view is about to appear on the screen.

  • ViewDidAppear - Called after the view appears - great place to start an animations or the loading of external data from an API.

  • ViewWillDisappear/DidDisappear - Same idea as ViewWillAppear/ViewDidAppear.

  • ViewDidUnload/ViewDidDispose - In Objective-C, this is where you do your clean-up and release of stuff, but this is handled automatically so not much you really need to do here.

Understanding the UIViewController lifecycle and passing of variables in iOS in Storyboards

On iOS, each view controller manages a single view and its subviews. Even if you used a UISplitViewController to put two identical view controllers on the screen at once, they would be two separate instances of the view controller class, and I believe storyboards instantiate a new view controller for each segue performed (though I could be wrong). Thus it's not only perfectly safe to use properties—it's expected practice.

UIViewController LifeCycle

In order to use an unwind segue, you start by setting up a method in the destination view controller.

@IBAction func unwind(segue: UIStoryboardSegue) {
// unwind
}

Note, that this method is placed in the destination view controller. The view controller being unwound to.

From here, we need not the segue's destinationViewController, but instead the sourceViewController.

@IBAction func unwind(segue: UIStoryboardSegue) {
if let source = segue.sourceViewController as MySourceViewController {
self.someProperty = source.someOtherProperty
}
}

But if we just want to do something once we unwind here no matter what, we can ignore the segue altogether (looks like what you're essentially doing there except for thinking you need a reference to the destinationViewController):

@IBAction func unwind(segue: UIStoryboardSegue) {
self.callLaunched = true
}

UIViewController and UIView Life cycles in iOS

In fact, the life cycle of UIViewController and UIView is not directly related, and they can be treated independently.

For UIViewController, its life cycle is affected by how it is used:

  1. If used as a childViewController in a container viewController (UINavigationController/UITabBarController/UISplitViewController, etc.), or as window.rootViewController, its lifecycle will be:

    init
    viewDidLoad
    willMoveToParentViewController:
    viewWillAppear:
    didMoveToParentViewController:
    viewDidAppear:
    willMoveToParentViewController:
    viewWillDisappear:
    didMoveToParentViewController:
    viewDidDisappear:
    dealloc
  2. If you just use viewController.view to add it to the other views, its life cycle may only be:

    init
    viewDidLoad
    viewWillAppear:
    viewDidAppear:
    dealloc

iOS view/controller lifecycle callback on screen unlock or app switch

The proper solution is to have the view controller register with NSNotificationCenter for the appropriate app lifecycle notification such as UIApplicationDidBecomeActiveNotification or UIApplicationWillEnterForegroundNotification.

Remember, these are app events, not view events which is why there are no standard methods in UIViewController or UIView for these.

UIViewController lifecycle calls in combination with state restoration

@property (nonatomic) BOOL firstLoad;

- (void)viewDidLoad {
[super viewDidLoad];
self.firstLoad = YES;
}

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

if (self.firstLoad) {
[self setupUI];
self.firstLoad = NO;
}
}

Thanks to @calvinBhai for the suggestion.



Related Topics



Leave a reply



Submit