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];
}
Related
I am new to iOS development. I am going to next screen using following statement.
locationViewController = [[LocationViewController alloc] initWithNibName:#"LocationViewController" bundle:nil];
[navigationController pushViewController:locationViewController animated:YES];
Now I want to go back to previous screen by tapping on custom back button on the top bar of the current screen.
use this:
-(IBAction)back:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
For home button:
NSArray *viewContrlls=[[self navigationController] viewControllers];
for( int i=0;i<[ viewContrlls count];i++)
{
id obj=[viewContrlls objectAtIndex:i];
if([obj isKindOfClass:[Rate_O_MeterViewController class]])
{
[[self navigationController] popToViewController:obj animated:YES];
return;
}
}
in place of Rate_O_MeterViewController give your controller name...add it in action of home button.
Try this,
appDelegate.m - didFinishLaunchingWithOptions method
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
//-----------navigation view--------------
UINavigationController *navHomeController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navHomeController;
Create a Back button:
UIBarButtonItem * backButton=[[UIBarButtonItem alloc]initWithTitle:#"Back" style:UIBarButtonItemStyleDone target:self action:#selector(goBack:)];
self.navigationItem.leftBarButtonItem=backButton;
And write a function:
-(void)goBack:(id)sender
{
[self.navigationController popViewControllerAnimated:YES]
}
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.
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.
MyView *view=[[[MyView alloc] init] autorelease];
[view setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:view animated:YES];
I have used flip transition on moving from one view controller to another.but my requirement is from left to right transition. Please help me to way out this problem thanks in advance.
here is my code:
You need to add QuartzCore Framework and then import #import <QuartzCore/QuartzCore.h>
MyView *next = [[MyView alloc] init];
CATransition *animation = [CATransition animation];
[self presentModalViewController:next animated:NO];
[animation setDuration:0.40];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
//[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
[[next.view layer] addAnimation:animation forKey:#"SwitchToView1"];
[next release];
I assume you are dismissing a view controller 2 from view controller 1. In view controller 2 you are using this
[self dismissModalViewControlleAnimated: NO];
Now In the 1st view controller, import of "QuartzCore" header and add viewWillAppear method with code
#import <QuartzCore/QuartzCore.h>
(void)viewWillAppear:(BOOL)animated {
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setDuration:0.50];
[animation setTimingFunction:
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.layer addAnimation:animation forKey:kCATransition];
}
- (void)slideView:(UIView*)view direction:(BOOL)isLeftToRight {
CGRect frame = view.frame;
frame.origin.x = (isLeftToRight) ? -320 : 320;
view.frame = frame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
frame.origin.x = 0;
view.frame = frame;
[UIView commitAnimations];
}
Why don't you use a UINavigationController and push the UIViewController instead of presenting it modally?
Edit:
To change your view-based app into a UINavigationController just add this to your AppDelegate
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *nvcontrol = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:nvcontrol.view];
Yes, you should do this through Navigational Controller.
Here is some code to help you, if you want to do it through Navigational Controller.
In AppDelegate.h:
#interface AppDelegate : UIResponder <UIApplicationDelegate,UINavigationControllerDelegate>{
UINavigationController *navController;
}
In AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// ViewController is your FirstViewController which loads over Window.
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.window.rootViewController = _viewController;
navController =[[UINavigationController alloc] initWithRootViewController:_viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
Then in your ViewController.m, in your button tapped function, you can do this:
NextViewController *nextController = [[NextViewController alloc] initWithNibName:#"NextViewController" bundle:nil];
[self.navigationController pushViewController:nextController animated:YES];
And that's all.
try this
[self.navigatationController pushViewController:view animated:YES];
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];
}