title: Warning - Attempt to present UIAlertController on VC
body: <p>The first time my app starts, I have a user registration screen where I capture name and email. 
  As part of text field validation, I display a <code>UIAlertController</code> if the validation fails. This validation method is called inside my Save button action and <code>UIAlertController</code> is displayed here as well. </p>
  
  <p>This was working fine when I had turned off Size Classes for my project. I have now updated my project to use Size Classes. Since then I have been getting this warning. </p>
  
  <pre><code>Warning: Attempt to present &lt;UIAlertController: 0x7b074660&gt; on &lt;WelcomeViewController: 0x7b0428d0&gt; whose view is not in the window hierarchy!
  </code></pre>
  
  <p>So now, if I click on Save it moves to the next screen without displaying an alert. </p>
  
  <p>Here is the code for what I described above:</p>
  
  <pre><code>- (IBAction)save:(id)sender {
  
  NSString *errorMessage = [self validateForm];
  
  if (errorMessage) {
      UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Detail Missing" message:errorMessage preferredStyle:UIAlertControllerStyleAlert];
  
      UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {}];
  
      [alert addAction:cancelAction];
  
      [self presentViewController:alert animated:YES completion:nil];
  
      return;
  }
  
  //Saving username and email in NSUSerDefaults
  NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
  [userData setObject:self.userTextField.text forKey:@"UserName"];
  [userData setObject:self.emailTextField.text forKey:@"Email"];
  [userData setBool:YES forKey:@"UserReg"]; }
  
  
  - (NSString *)validateForm {
      NSString *errorMessage;
  
      if (![self.userTextField.text isValidText]){
          errorMessage = @"Please enter your name";
      } else if (![self.emailTextField.text isValidEmail]){
          errorMessage = @"Please enter a valid email address";
      }
  
      return errorMessage;
  }
  </code></pre>
  
  <p>In <code>AppDelegate.m</code> I perform a check if user information has been stored or not. If it hasn't been, my welcome screen is shown (where i capture details) else I load the main app screen. 
  If I enter user details correctly the first time and press save, the app functions normally without any problem. </p>
  
  <p>I have gone through answers for a similar problem, unfortunately they did not help me as my UIAlertController is called in the save button action rather than <code>viewDidLoad</code> or <code>viewDidAppear</code> or <code>viewWillAppear</code>. </p>
  
  <p>What can I do to solve this issue?</p>
  
  <p><strong>Additional Information for Rob's response</strong></p>
  
  <p>I've tried both approaches suggested by Rob - one where I just look for the view controller's view address and other where I subclass UIView and assign a tag to the root view of WelcomeViewController. Both results are similar, in that I can find my view in the hierarchy.</p>
  
  <p>Here are results with using subclass and tag:</p>
  
  <pre><code>    &lt;WelcomeViewController 0x78ea7850&gt;, state: appeared, view: &lt;WelcomeView 0x78e7b210&gt;
     + &lt;UINavigationController 0x78e58c00&gt;, state: disappeared, view: &lt;UILayoutContainerView 0x78e5bcb0&gt; not in the window, presented with: &lt;_UIFullscreenPresentationController 0x78ef3ac0&gt;
     |    | &lt;WardrobeListTableViewController 0x78ef3940&gt;, state: disappeared, view: &lt;UITableView 0x7a357600&gt; not in the window
  </code></pre>
  
  <p>Recursive Hierarchy</p>
  
  <pre><code>&lt;UIWindow: 0x799ad460; frame = (0 0; 320 568); gestureRecognizers = &lt;NSArray: 0x799adac0&gt;; layer = &lt;UIWindowLayer: 0x799acfe0&gt;&gt;
     | &lt;WelcomeView: 0x78e7b210; frame = (0 0; 320 568); autoresize = W+H; tag = 10; layer = &lt;CALayer: 0x78e7b0c0&gt;&gt;
     |    | &lt;UINavigationBar: 0x78e7aed0; frame = (0 20; 320 44); opaque = NO; autoresize = RM+BM; gestureRecognizers = &lt;NSArray: 0x78e6fb60&gt;; layer = &lt;CALayer: 0x78e7ade0&gt;&gt;
     |    |    | &lt;_UINavigationBarBackground: 0x78e70bd0; frame = (0 0; 320 44); userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e70d90&gt;&gt;
     |    |    |    | &lt;_UIBackdropView: 0x78e5df70; frame = (0 0; 320 44); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = &lt;_UIBackdropViewLayer: 0x78e59050&gt;&gt;
     |    |    |    |    | &lt;_UIBackdropEffectView: 0x78e58620; frame = (0 0; 320 44); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; animations = { filters.colorMatrix.inputColorMatrix=&lt;CABasicAnimation: 0x799b3730&gt;; }; layer = &lt;CABackdropLayer: 0x78e582b0&gt;&gt;
     |    |    |    |    | &lt;UIView: 0x78e57b40; frame = (0 0; 320 44); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e57b10&gt;&gt;
     |    |    |    | &lt;UIImageView: 0x78e706b0; frame = (0 44; 320 0.5); userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e70580&gt;&gt;
     |    |    | &lt;UINavigationItemView: 0x78e74390; frame = (91.5 8; 137 27); opaque = NO; userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e74260&gt;&gt;
     |    |    |    | &lt;UILabel: 0x78e74060; frame = (0 3.5; 137 21.5); text = 'User Registration'; opaque = NO; userInteractionEnabled = NO; layer = &lt;_UILabelLayer: 0x78e73f30&gt;&gt;
     |    |    | &lt;_UINavigationBarBackIndicatorView: 0x799b6a00; frame = (8 11.5; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = &lt;CALayer: 0x799b6ba0&gt;&gt;
     |    | &lt;UITextView: 0x79373400; frame = (0 64; 320 90); text = 'Welcome to the Baby Wardr...'; clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = &lt;NSArray: 0x78e6dfb0&gt;; layer = &lt;CALayer: 0x78e6fa00&gt;; contentOffset: {0, 0}; contentSize: {320, 88}&gt;
     |    |    | &lt;&lt;_UITextContainerView: 0x78e6c9c0; frame = (0 0; 320 88); layer = &lt;_UITextTiledLayer: 0x78e6cca0&gt;&gt; minSize = {320, 0}, maxSize = {3.4028235e+38, 3.4028235e+38}, textContainer = &lt;NSTextContainer: 0x79886290 size = (320.000000,340282346638528859811704183484516925440.000000); widthTracksTextView = YES; heightTracksTextView = NO&gt;; exclusionPaths = 0x0; lineBreakMode = 0&gt;
     |    |    |    | &lt;_UITileLayer: 0x78e4fab0&gt; (layer)
     |    |    |    | &lt;_UITileLayer: 0x78e54860&gt; (layer)
     |    |    |    | &lt;_UITileLayer: 0x78e656e0&gt; (layer)
     |    |    |    | &lt;_UITileLayer: 0x78e5a060&gt; (layer)
     |    |    |    | &lt;UITextSelectionView: 0x78e63900; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e637b0&gt;&gt;
     |    |    | &lt;UIImageView: 0x799b7090; frame = (0 87.5; 600 2.5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = &lt;CALayer: 0x799b7110&gt;&gt;
     |    |    | &lt;UIImageView: 0x799b74e0; frame = (317.5 8; 2.5 82); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = &lt;CALayer: 0x799b7560&gt;&gt;
     |    | &lt;UITextField: 0x78e7e2a0; frame = (16 174; 288 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = &lt;NSArray: 0x79996a90&gt;; layer = &lt;CALayer: 0x78e7e3e0&gt;&gt;
     |    |    | &lt;_UITextFieldRoundedRectBackgroundViewNeue: 0x78e7b600; frame = (0 0; 288 30); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e7b5d0&gt;&gt;
     |    |    | &lt;UITextFieldLabel: 0x78e7b820; frame = (7 1; 274 27); text = 'Name'; opaque = NO; userInteractionEnabled = NO; layer = &lt;_UILabelLayer: 0x78e7b7d0&gt;&gt;
     |    | &lt;UITextField: 0x78efbec0; frame = (16 214; 288 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = &lt;NSArray: 0x799ae7c0&gt;; layer = &lt;CALayer: 0x78e7f420&gt;&gt;
     |    |    | &lt;_UITextFieldRoundedRectBackgroundViewNeue: 0x78e7cea0; frame = (0 0; 288 30); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = &lt;CALayer: 0x78e7d080&gt;&gt;
     |    |    | &lt;UITextFieldLabel: 0x78e7bef0; frame = (7 1; 274 27); text = 'Email Address'; opaque = NO; userInteractionEnabled = NO; layer = &lt;_UILabelLayer: 0x78e7c0f0&gt;&gt;
     |    | &lt;UIButton: 0x799ae9b0; frame = (80 264; 160 30); opaque = NO; autoresize = RM+BM; layer = &lt;CALayer: 0x799aebb0&gt;&gt;
     |    |    | &lt;UIButtonLabel: 0x78e5e460; frame = (25 6; 109.5 18); text = 'Save &amp; Proceed'; alpha = 0.2; opaque = NO; userInteractionEnabled = NO; layer = &lt;_UILabelLayer: 0x78e5e0f0&gt;&gt;
     |    | &lt;_UILayoutGuide: 0x78e73db0; frame = (0 0; 0 20); hidden = YES; layer = &lt;CALayer: 0x78e73e70&gt;&gt;
     |    | &lt;_UILayoutGuide: 0x78e66ea0; frame = (0 568; 0 0); hidden = YES; layer = &lt;CALayer: 0x78e7cb10&gt;&gt;
  </code></pre>
  
  <p>Any further suggestions on how to solve this issue?  </p>
  
  <p><strong>Additional information for Kiddae</strong>
  As I mentioned, I perform a check in AppDelegate.m to decide which viewController to show. Here is the code:</p>
  
  <pre><code>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      // Override point for customization after application launch.
      self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
  
      //Check if user data has been saved &amp; determine the initial view controller
      NSString *identifier;
      BOOL isSaved = [[NSUserDefaults standardUserDefaults] boolForKey:@"UserReg"];
      if (isSaved)
      {
          identifier=@"Wardrobe";
      }
      else
      {
          identifier=@"Welcome";
      }
  
      UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
      UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:identifier];
  
      self.window.rootViewController = viewController;
      [self.window makeKeyAndVisible];
  
      return YES;
  }
  </code></pre>