My first view displays an image and action indicator while web-servers and database function are run in that background. I want the application to go to my tab view when the functions have been completed. How do I do this?
Here is what the views look like.
What I have tried:
TabBarViewController *tab = [[TabBarViewController alloc]init];
[self presentViewController:tab animated:NO completion:nil];
and
[self performSegueWithIdentifier:#"first" sender:self];
Please can you help my to understand how to do this. I have spent many hours googling this problem and couldn't work out how to do it.
Thanks
EDIT: Added Code
Since you are downloading data you can get a call when the downloading request gets finished
like the method below
- (void)requestFinished:(ASIHTTPRequest *)request
and in this method you can very well present your TabBarViewController.
You can use GCD to make this happen.
For instance in your firstViewController where you trigger downloading you can do:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[model downloadData];
dispatch_sync(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"YourSegueIdentifier" sender:self];
});
});
I assume your downloadData method is synchronous, if not you can use notifications in your model. Once data is retrieved you could postNamedNotification from NSNotificationCenter and in firstViewController you could register for notification and after receiving it you would call performSegueWithIdentifier
You Can Declare A separate Method for that.
Call the below method when your function completes.
[self performSelector:#selector(gotonext:) withObject:nil afterDelay:4.0];
-(void)gotonext;
{
TabBarViewController *tab = [[TabBarViewController alloc]init];
[self presentViewController:tab animated:NO completion:nil];
}
Take one splashView Image at starting, like bellow...
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
UIImageView *splashView;
}
#property (nonatomic, retain) UIImageView *splashView;
#end
in AppDelegate.m file...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
splashView = [[UIImageView alloc] initWithFrame:iphoneFrame];
splashView.image = [UIImage imageNamed:#"Default"];
[self.window addSubview:splashView];
[self.window makeKeyAndVisible];
UIViewController *viewController1 = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil] autorelease];
UINavigationController *navviewController1=[[UINavigationController alloc]initWithRootViewController:viewController1];
navviewController1.title = #"FirstTitle";
// navviewController1.navigationBarHidden=YES;
UIViewController *viewController2 = [[[yourviewController2 alloc] initWithNibName:#"yourviewController2" bundle:nil] autorelease];
UINavigationController *navviewController2=[[UINavigationController alloc]initWithRootViewController:viewController2];
// navviewController2.navigationBarHidden=YES;
navviewController2.title = #"SecondTitle";
UIViewController *viewController3 = [[[yourviewController3 alloc] initWithNibName:#"yourviewController2" bundle:nil] autorelease];
UINavigationController *navviewController3=[[UINavigationController alloc]initWithRootViewController:viewController3];
// navviewController3.navigationBarHidden=YES;
navviewController3.title = #"ThirdTitle";
//..... and so on depend on your requirement
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navviewController1, navviewController2 , navviewController3 ,nil];
[self performSelector:#selector(loadViewIphone) withObject:nil afterDelay:2.0];//**add this line at your all data are loading completed**
}
else
{
splashView = [[UIImageView alloc] initWithFrame:ipadFrame];
splashView.image = [UIImage imageNamed:#"Default_iPad"];
[self.window addSubview:splashView];
[self.window makeKeyAndVisible];
[self performSelector:#selector(loadViewIpad) withObject:nil afterDelay:2.0];
}
[self.window makeKeyAndVisible];
return YES;
}
-(void)loadViewIphone
{
[splashView removeFromSuperview];
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionFromBottom];
[animation setDuration:1.0];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseInEaseOut]];
[[self.window layer] addAnimation:animation forKey:#"transitionViewAnimation"];
[self.window makeKeyAndVisible];
}
i hope this help you...
Hm... What if you put
TabBarViewController *tab = [[TabBarViewController alloc]init];
[self presentViewController:tab animated:NO completion:nil];
In
dispatch_async(dispatch_get_main_queue(), ^{
//stop the loader once the database stuff has finished and get rid of the text
[[self firstLoader]stopAnimating];
self.downloadingLabel.text = #"";
});
UPDATE: If you want to do this sync
dispatch_sync(a_queue, ^{ wait_for_me(); });
And after that present your VC.
Related
I need to create a split view application that starts with basic view that I customize manually. Then I need to transition to the SplitView or push the master/detail table views onto the stack for the phone implementation.
The strategy I was planning to use would be placing the basic view into the detail pane on the SplitView controller, and while it was there just hide the side panel and button for the left pane in their respective orientations.
Is there a better way? Can I use a "plain" view as my root view, then switch it programmatically to a UISplitView?
For the phone version - this isn't really a problem. Since the navigation controller is the root view controller - I can just push more views onto the stack.
For the iPad - you cannot push a UISplitView controller onto the Navigation stack. I'd really like to do this so I have some concept of "back". I can create it programmatically - but before I do - I'd be interested in some other options if they exist.
I want to use Storyboards for this application - and the target version is iOS 5 - for ARC.
I've done this by replacing the root of the app. As first screen I had a LoginViewController, and when the login was successful, switched that ViewController with a UISplitViewController. You can do this animated too.
Edit:
Here is my code from the UIStoryboardSegue subclass:
- (void) perform
{
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
UIViewController *sourceViewController = (UIViewController *)self.sourceViewController;
UISplitViewController *destinationViewController = (UISplitViewController *)self.destinationViewController;
UIWindow *window = appDelegate.window;
window.rootViewController = destinationViewController;
window.rootViewController = sourceViewController;
[UIView transitionWithView:sourceViewController.view.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
window.rootViewController = destinationViewController;
}
completion:^(BOOL finished){
}];
}
try this code:
you can add your LoginViewcontroller as A root view-controller in Delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[LogInViewController alloc] initWithNibName:#"LogInViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
and your loginButton Action:
-(IBAction)loginclick:(id)sender
{
objAppdelegate = (yourProjectnameDelegate *) [[UIApplication sharedApplication]delegate];
NSMutableArray *array = [NSMutableArray array];
HomeSpilitView = [[[UISplitViewController alloc] init]autorelease];
HomeMster = [[HomeSpilitViewController alloc] initWithNibName:#"HomeSpilitViewController" bundle:nil];
masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:HomeMster] autorelease];
HomeMster.title=#"Title home";
masterNavigationController.navigationBar.tintColor =[UIColor colorWithRed:255/255.0 green:108/255.0 blue:61/255.0 alpha:0.1];
[array addObject:masterNavigationController];
HomeDetailsViewController *HomeDetailsViewControllers = [[HomeDetailsViewController alloc] initWithNibName:#"HomeDetailsViewController" bundle:nil];
detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:HomeDetailsViewControllers] autorelease];
detailNavigationController.navigationBar.tintColor =[UIColor colorWithRed:255/255.0 green:108/255.0 blue:61/255.0 alpha:0.1];
HomeDetailsViewControllers.title=#"details title";
HomeMster.objHomeDetailsViewcontroller=HomeDetailsViewControllers;
HomeSpilitView.delegate = HomeDetailsViewControllers;
[array addObject:detailNavigationController];
[HomeSpilitView setViewControllers:array];
[objAppdelegate.window setRootViewController:HomeSpilitView];
}
//===for animation
UIInterfaceOrientation interfaceOrientation = HomeSpilitView.interfaceOrientation;
NSString *subtypeDirection;
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
subtypeDirection = kCATransitionFromTop;
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
subtypeDirection = kCATransitionFromBottom;
}
else {
subtypeDirection = kCATransitionFromRight;
}
[objAppdelegate.window setRootViewController:HomeSpilitView];
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:subtypeDirection];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[objAppdelegate.window layer] addAnimation:animation forKey:#"SwitchToView1"];
I am getting an different image at the start of the app like a splash screen then i am getting my actual image that i placed in coding.
I placed the splash screen with the following code in my didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.tabBarController;
self.tabBarController.delegate=self;
[window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
LoginViewController *vc = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
self.loginNav = [[UINavigationController alloc] initWithRootViewController:vc];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults valueForKey:#"UserName"] &&[userDefaults valueForKey:#"Password"])
{
vc.username=[userDefaults valueForKey:#"UserName"];
vc.password=[userDefaults valueForKey:#"Password"];
vc.autoLogin=YES;
[vc loginSelectorMethod];
}
else
{
[self.window addSubview:self.loginNav.view];
[self.window makeKeyAndVisible];
}
splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
splashView.image = [UIImage imageNamed:#"splashscreen.png"];
[window addSubview:splashView];
[window bringSubviewToFront:splashView];
[self performSelector:#selector(removeSplash) withObject:nil afterDelay:3.0];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
NSLog(#"Registering for remote notifications");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
return YES;
}
Before the splash screen appears , the "Arrow.png" image appears then my splash screen appers.
If i delete the "Arrow.png" then in place of that image another images appears i.e., "aboutus.png" like that it continues.
I searched in my project for the "Arrow.png" it only appears once in my whole project in the coding.
here you add subiview as a tabbar like bellow..
[window addSubview:tabBarController.view];
after you add loginview like bellow..
[self.window addSubview:self.loginNav.view];
and after that you add splashscreen like bellow..
splashView.image = [UIImage imageNamed:#"splashscreen.png"];
[window addSubview:splashView];
So this is the problem that you seen more then screen instead of splashscreen.
use bellow code...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
splashView.image = [UIImage imageNamed:#"splashscreen.png"];
[window addSubview:splashView];
[window bringSubviewToFront:splashView];
[self performSelector:#selector(removeSplash) withObject:nil afterDelay:3.0];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
NSLog(#"Registering for remote notifications");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
return YES;
}
and in removeSplash method add this view as a subview of window like bellow..
-(void)removeSplash{
[splashView removeFromSuperView];
LoginViewController *vc = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
self.loginNav = [[UINavigationController alloc] initWithRootViewController:vc];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults valueForKey:#"UserName"] &&[userDefaults valueForKey:#"Password"])
{
vc.username=[userDefaults valueForKey:#"UserName"];
vc.password=[userDefaults valueForKey:#"Password"];
vc.autoLogin=YES;
[vc loginSelectorMethod];
}
else
{
[self.window addSubview:self.loginNav.view];
[self.window makeKeyAndVisible];
}
}
Have you set any Launch image in ur project setting or have you put any image named "Default.png" in your project bundle this kind of image get detect by OS automatically while launch our app please check this 2 points.
edit:-
Than the problem is conflict in TabBar & LoginView & splaceImage.
For this do below stuff I thing this resolve your double image issue.
First, put below code in your DidFinishLaunching() method
//Delay second that how much time u show your splace image
int64_t delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//Do need Full like Add Login View or Add TabbBar
//Remove SplaceImageView From Window
});
splashView = [[UIImageView alloc] initWithFrame:self.window.frame];
splashView.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
[self.window addSubview:splashView];
[self.window bringSubviewToFront:splashView];
return YES;
and also one more thing add default splace image like
for iPhone Portrait Default.png.
for iPad, Portrait Default-Portrait~ipad.png
follow as apple document for default image and then check.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
self.sql_ = [SQLDb initEngine];
[self setupControllers]; /// Set up Yor ToolBar Controller
self.hvController = [[HomeViewController alloc] init];
self.window.rootViewController = self.hvController;
[self.window makeKeyAndVisible];
[self setupSplash];
return YES;
}
-(void) setupSplash
{
self.imvSplash = [[UIImageView alloc] initWithFrame:self.window.bounds];
if( IS_IPHONE_5 )
[self.imvSplash setImage: [UIImage imageNamed:#"Default-568h#2x.png"]];
else
[self.imvSplash setImage: [UIImage imageNamed:#"splash.png"]];
[self.window addSubview: self.imvSplash];
[NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:#selector(hideSplash:) userInfo:nil repeats:NO];
}
- (void)hideSplash:(NSTimer *)theTimer
{
[UIView animateWithDuration:1.0
delay:0.1
options: UIViewAnimationCurveEaseOut
animations:^{
self.imvSplash.alpha = 0.0;
self.ngNavigationController.view.alpha = 1.0;
}
completion:^(BOOL finished)
{
//[self.ngController setupImageAction];
[self.imvSplash removeFromSuperview];
}];
}
I need to add a tabbarcontroller with ViewControllers when Facebook login is successful.BUt Couldn't understand how?
I have in appDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
SearchView *first=[[SearchView alloc]
initWithNibName:#"SearchView" bundle:nil];
Login *second=[[Login alloc]initWithNibName:#"Login" bundle:nil];
second.title=#"Login";
NSArray *viewArray=[[NSArray alloc] initWithObjects: first,second,nil];
tabBarController=[[UITabBarController alloc] init];
[tabBarController setViewControllers:viewArray animated:NO];
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
[viewArray release];
[first release];
[second release];
return YES;
}
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if (!error) {
FBLogin *fblogin=[[FBLogin alloc]initWithNibName:#"FBLogin" bundle:nil];
[self.window addSubview:fblogin.view];
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[[FBSession activeSession] closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter]
postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
In FBLogin.m :
-(void)viewDidAppear:(BOOL)animated
{
SearchView *searchViewController=[[SearchView alloc]initWithNibName:#"SearchView" bundle:nil];
UserProfile *userprofile=[[UserProfile alloc]initWithNibName:#"UserProfile" bundle:nil];
userprofile.title=#"My Profile";
LogOut *logout=[[LogOut alloc]initWithNibName:#"LogOut" bundle:nil];
logout.title=#"Sign Out";
tab=[[UITabBarController alloc]init];
tab.viewControllers=[NSArray arrayWithObjects:searchViewController,userprofile,logout, nil];
[self presentModalViewController:tab animated:NO];
}
But I couldnot see the tabbarcontroller added in fBLogin.I can see an empty white view.
Y is it so ?
how can I achieve it ?
just set and initialize the UITabBarController in AppDelegate and when you sign in successfull just call UITabBarController as a rootViewController of window with our custom method For Ex...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *viewController1 = [[[yourViewController1 alloc] initWithNibName:#"yourViewController1" bundle:nil] autorelease];
UINavigationController *navviewController1=[[UINavigationController alloc]initWithRootViewController:viewController1];
UIViewController *viewController2 = [[[yourViewController2 alloc] initWithNibName:#"yourViewController2" bundle:nil] autorelease];
UINavigationController *navviewController2=[[UINavigationController alloc]initWithRootViewController:viewController2];
UIViewController *viewController3 = [[[yourViewController3 alloc] initWithNibName:#"yourViewController3" bundle:nil] autorelease];
UINavigationController *navviewController3=[[UINavigationController alloc]initWithRootViewController:viewController3];
UIViewController *viewController4 = [[[yourViewController4 alloc] initWithNibName:#"yourViewController4" bundle:nil] autorelease];
UINavigationController *navviewController4=[[UINavigationController alloc]initWithRootViewController:viewController4];
UIViewController *viewController5 = [[[yourViewController5 alloc] initWithNibName:#"yourViewController5" bundle:nil] autorelease];
UINavigationController *navviewController5=[[UINavigationController alloc]initWithRootViewController:viewController5];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navviewController1, navviewController2,navviewController3,navviewController4,navviewController5, nil];
SearchView *first=[[SearchView alloc]
initWithNibName:#"SearchView" bundle:nil];
Login *second=[[Login alloc]initWithNibName:#"Login" bundle:nil];
second.title=#"Login";
NSArray *viewArray=[[NSArray alloc] initWithObjects: first,second,nil];
yourTabBarController=[[UITabBarController alloc] init];
[yourTabBarController setViewControllers:viewArray animated:NO];
[self.window addSubview:yourTabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
when you sign in success full just call bellow our custom method..
-(void)loadTabBarFromDelegate
{
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionFade];
[animation setDuration:0.5];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseInEaseOut]];
[[self.window layer] addAnimation:animation forKey:#"transitionViewAnimation"];
}
and when you want to call this method just create object and call this method like bellow...
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate loadTabBarFromDelegate];
i hope this help you...
Try moving your code from viewDidLoad to viewDidAppear.
I have an UITabBarController, when initial run, I want to overlay a login view controller but received error.
Unbalanced calls to begin/end appearance transitions for < UITabBarController: 0x863ae00 >.
Below is the code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *lessonVC = [[[LessonViewController alloc] initWithNibName:#"LessonViewController" bundle:nil] autorelease];
UIViewController *programVC = [[[ProgramViewController alloc] initWithNibName:#"ProgramViewController" bundle:nil] autorelease];
UIViewController *flashcardVC = [[[FlashCardViewController alloc] initWithNibName:#"FlashCardViewController" bundle:nil] autorelease];
UIViewController *moreVC = [[[MoreViewController alloc] initWithNibName:#"MoreViewController" bundle:nil] autorelease];
UINavigationController *lessonNVC = [[[UINavigationController alloc] initWithRootViewController:lessonVC] autorelease];
UINavigationController *programNVC = [[[UINavigationController alloc] initWithRootViewController:programVC] autorelease];
UINavigationController *flashcardNVC = [[[UINavigationController alloc] initWithRootViewController:flashcardVC] autorelease];
UINavigationController *moreNVC = [[[UINavigationController alloc] initWithRootViewController:moreVC] autorelease];
self.tabBarController = [[[UITabBarController alloc] init/*WithNibName:nil bundle:nil*/] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:lessonNVC, programNVC, flashcardNVC, moreNVC, nil];
self.tabBarController.selectedIndex = 0;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
if (![[ZYHttpRequest sharedRequest] userID])
{
// should register or login firstly
LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:#"LoginViewController"
bundle:nil];
loginVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.tabBarController presentModalViewController:loginVC animated:YES];
ZY_SAFE_RELEASE(loginVC);
}
return YES;
}
Anyone who can help me? Thanks in advance!
You need to wait to present the modal view controller until the next run loop. I ended up using a block (to make things more simple) to schedule the presentation for the next run loop:
Update:
As mentioned by Mark Amery below, just a simple dispatch_async works, there's no need for a timer:
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.container presentModalViewController:nc animated:YES];
});
/* Present next run loop. Prevents "unbalanced VC display" warnings. */
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.container presentModalViewController:nc animated:YES];
});
I suspect the problem is that you're trying to call presentModalViewController: before the tab bar is done loading. Try moving the final logic onto the next event loop:
[self.window makeKeyAndVisible];
[self performSelector:(handleLogin) withObject:nil afterDelay:0];
}
- (void)handleLogin
{
if (![[ZYHttpRequest sharedRequest] userID])
{
// should register or login firstly
LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:#"LoginViewController"
bundle:nil];
loginVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.tabBarController presentModalViewController:loginVC animated:YES];
ZY_SAFE_RELEASE(loginVC);
}
}
[self.tabBarController presentModalViewController:loginVC animated:**NO**];
I had a similar problem when tried to presentModalViewController (my welcome screen) in main view's viewWillAppear. Is was solved just by moving the modal VC call to viewDidAppear.
[self performSelector:#selector(modaltheView) withObject:self afterDelay:0.1];
-(void)modaltheView
{
[self.container presentModalViewController:nc animated:YES];
}
I have following code in my Application.
Comments in my code will specify "My Question".
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarObj = [[UITabBarController alloc] init];
vctr0=[[SplashScrn alloc] initWithNibName:#"SplashScrn" bundle:nil];
vctr1=[[SearchViewController alloc] initWithNibName:#"SearchViewController" bundle:nil];
vctr2=[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *nvctr1=[[[UINavigationController alloc]initWithRootViewController:vctr1] autorelease];
UINavigationController *nvctr2=[[[UINavigationController alloc]initWithRootViewController:vctr2] autorelease];
tabBarObj.viewControllers=[NSArray arrayWithObjects:nvctr1,nvctr2,nil];
[window addSubview:vctr0.view];
[window makeKeyAndVisible];
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(hideSplash) userInfo:nil repeats:NO];
}
-(void)hideSplash
{
/* CATransition *tr=[CATransition animation];
tr.duration=0.75;
tr.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
tr.type=kCATransitionMoveIn;
tr.subtype=kCATransitionFromRight;
[vctr0.view.layer addAnimation:tr forKey:nil]; */
// actually here i want to remove vctr0 - viewcontroller 0 - a splash screen
// e.g [vctr0 removeFromSuperView];
// [window addSubView:tabBarObj];
// I don't know the correct code for this.
}
Thanks in advance for helping me.
Try
[vctr0.view removeFromSuperview];
I had done some R & D on my code.
By the way, I got the solution as I wanted.
I implemented Following code & It was successful.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarObj = [[UITabBarController alloc] init];
vctr0=[[SplashScrn alloc] initWithNibName:#"SplashScrn" bundle:nil];
vctr1=[[SearchViewController alloc] initWithNibName:#"SearchViewController" bundle:nil];
vctr2=[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *nvctr1=[[[UINavigationController alloc]initWithRootViewController:vctr1] autorelease];
UINavigationController *nvctr2=[[[UINavigationController alloc]initWithRootViewController:vctr2] autorelease];
tabBarObj.viewControllers=[NSArray arrayWithObjects:nvctr1,nvctr2,nil];
[window addSubview:vctr0.view];
[window makeKeyAndVisible];
[NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:#selector(hideSplash) userInfo:nil repeats:NO];
}
-(void)hideSplash
{
CATransition *tr=[CATransition animation];
tr.duration=0.75;
tr.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
tr.type=kCATransitionMoveIn;
tr.subtype=kCATransitionFromRight;
[tabBarObj.view.layer addAnimation:tr forKey:nil];
[window addSubview:tabBarObj.view];
}