Reputation: 1643
I've been searching the web and Stack Overflow for hours and I cannot resolve this issue. here's hoping you all see my mistake, because I just can't find it.
I have a simple storyboard-based application I just started. The initial ViewController is an instance of UITabBarController with the two dummy ViewControllers from the template. Upon start up I need to check if the device is logged into an external service. If not I will show a modal ViewController that will allow the user to authenticate, if the device is authenticated then I will just show the FirstViewController.
The following steps are everything I have done since creating the project:
viewDidLoad
in the UITabBarController subclassWhen I run the application the modal segue does not fire, the first ViewController of the UITabBarController is shown, and I get the following output in XCode:
Warning: Attempt to present <AuthenticateViewController: 0x83c0c10> on <EPTabBarController: 0x83be600> whose view is not in the window hierarchy!
Relevant code below, in fact the only code I have added so far. Please let me know if screenshots or additional information would be useful. Thanks in advance for your help.
EPTabBarController, subclass of UITabBarController:
#import "EPTabBarController.h"
#import "AuthenticateViewController.h"
@interface EPTabBarController ()
@end
@implementation EPTabBarController
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
Upvotes: 10
Views: 9049
Reputation: 445
How about simply calling your code in viewDidAppear?
- (void)viewDidAppear
{
[super viewDidAppear];
[self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}
However, I am still unsatisfied of these solutions because the original view still shows up for a fraction of a second.
Any idea on how to show the new modal without showing the original view first?
Upvotes: 3
Reputation: 9836
The issue is inside
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}
you are trying to present another view( AuthenticateViewController
) while your current view( EPTabBarController
) is not yet loaded in the window hierarchy.
So first let your EPTabBarController
to get loaded in window hierarchy and then present AuthenticateViewController
.
Give this a try
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:@selector(loadAuthenticateViewController)
withObject:nil
afterDelay:1.0];
}
-(void)loadAuthenticateViewController
{
[self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}
Upvotes: 14
Reputation: 30043
When you really want to be in control, use something like this:
@implementation UeInitialisationViewController
BOOL didLoad;
BOOL wantPush;
- (id)init {
self = [super init];
if (self) { didLoad = NO; wantPush = NO; }
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
didLoad = YES;
if (wantPush == YES)
[self performSelector:@selector(pushToMainView)
withObject:nil afterDelay:0.0001];
}
- (void)pushToMainView {
if (didLoad == YES)
[self performSegueWithIdentifier:@"pushToMainView" sender:self];
else
wantPush = YES;
}
@end
This will fire the Segue pushToMainView
when you message [controller pushToMainView]
but holds back, until the view is loaded.
Upvotes: 2