Why can't I launch this modal view from didFinishLaunchingWithOptions? - iphone

I am trying to do something pretty easy, in my estimation:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
prefs = [NSUserDefaults standardUserDefaults];
BOOL IsLoggedIn = [prefs boolForKey:#"IsLoggedIn"];
if(IsLoggedIn == NO)
{
//Show login controller
LoginViewController *lvc = [[LoginViewController alloc] initWithNibName:nil bundle:nil];
[self.tabBarController presentModalViewController:lvc animated:NO];
[lvc release];
}
else if(IsLoggedIn == YES)
{
//Continue doing crap
}
// Override point for customization after application launch.
// Add the tab bar controller's current view as a subview of the window
self.window.rootViewController = self.tabBarController;
NSArray *tabs = self.tabBarController.viewControllers;
UIViewController *tbInvoice = [tabs objectAtIndex:0];
tbInvoice.tabBarItem.image = [UIImage imageNamed:#"Open-Mail.png"];
UIViewController *tbClient = [tabs objectAtIndex:1];
tbClient.tabBarItem.image = [UIImage imageNamed:#"Breifcase.png"];
[self.window makeKeyAndVisible];
return YES;
}
When using the debugger, I see it enter if(IsLoggedIn == NO) and run the LoginViewController code, but the view never shows.
It's driving me crazy.
I tried running the code after [self.windoow makeKeyAndVisible], but it didn't change anything.
This code looks like every example I've seen. Can anyone see what I'm doing wrong?
Thanks in advance,
Clif

I came up with this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
if(!loggedIn)
{
// Launch the app with login controller as the rootController
self.window.rootViewController = loginController;
// ...but switch to the original controller as soon as the UI is presented
dispatch_async(dispatch_get_main_queue(), ^{
self.window.rootViewController = originalRootController;
// ...and silently present the login controller again with no noticeable changes
[originalRootController presentViewController:loginController
animated:NO
completion:NULL];
});
}

Hpoe this post will give you some idea.

Related

How to Redirect to home tab after login Iphone App?

In my AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
//Get uer ID from user defaults
NSString *userid = [defaults objectForKey:#"UserId"];
if([userid isEqualToString:#""]){
login = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
[window addSubview:login.view];
} else {
[window addSubview:[rootTabBarController view]];
}
[self.window makeKeyAndVisible];
return YES;
}
and after login success i have this code
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:serverOutput forKey:#"UserId"];
//show tabbar app
NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
[appsDelegate.window addSubview:[appsDelegate.rootTabBarController view]];
so the question is how can i redirect to specific tab [Home tab FOR EXAMBLE]?
[appDelegate.rootTabBarController setSelectedIndex:GiveIndexOfTab]; // give index of home tab for ex. 0
If you want to jump to a specific tab without intercepting the tabBar, rather than the first default tab
use
[appsDelegate.rootTabBarController setSelectedIndex:2]; // 2 is a pseudo index i have assigned
For tabbar controller,
SelectedIndex propery helps you to manage its behavior.
Use
setSelectedIndex:Index
method. It'll solve your purpose.
Thanks.

iOS 6 - State Preservation and Restoration

I have implemented iOS 6 API for state saving, it works - after I quit the app and launch back in for some milliseconds the restored view controller fly in, but then it's replaced by the main view controller I display at launch.
I'm setting every time the app launch the root view of the main window, so this must be the issue.
Here is my code:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self commonInitializationLaunching:launchOptions];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self commonInitializationLaunching:launchOptions];
return YES;
}
- (void)commonInitializationLaunching:(NSDictionary *)launchOptions
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
static NSString *const kKeychainItemName = #"OAuthGoogleReader";
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
GTMOAuth2Authentication *auth;
auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
clientID:kClientID
clientSecret:kClientSecret];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
BOOL isSignedIn = [auth canAuthorize];
if (isSignedIn) {
NSLog(#"Signed");
}else{
NSString *scope = #"https://www.google.com/reader/api/";
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:scope
clientID:kClientID
clientSecret:kClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[self.navController pushViewController:viewController animated:YES];
// self.window.rootViewController = viewController;
}
});
}
You can see that in -(void)commonInitializationLaunching:(NSDictionary *)launchOptions
I'm setting my window's root view. I don't know what to put in there. Perhaps check if there is saved state and then load this method? But how?
Thanks!
Here is what I've tried following Rob's advice:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (!self.isRestored) {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
[self commonInitializationLaunching:launchOptions];
[self.window makeKeyAndVisible];
return YES;
}
with nothing in willFinishLaunching...
I also removed by window code from my commonInitializationLaunching method.
Storyboards will do most of the heavy lifting for you, such as restoring the window. Using code, however, will not restore the window. You will need to hold on to your root view controller using the encoder. Your code will look something like this:
NSString * const AppDelegateRootVCKey = #"AppDelegateRootVCKey";
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
[coder encodeObject:self.window.rootViewController forKey:AppDelegateRootVCKey];
}
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
// Grabs the preserved root view controller.
UIViewController * vc = [coder decodeObjectForKey:AppDelegateRootVCKey];
if (vc) {
UIWindow * window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = vc;
window.restorationIdentifier = NSStringFromClass([window class]);
// The green color is just to make it obvious if our view didn't load properly.
// It can be removed when you are finished debugging.
window.backgroundColor = [UIColor greenColor];
self.window = window;
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (!self.window) {
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// The blue color is just to make it obvious if our view didn't load properly.
// It can be removed when you are finished debugging.
window.backgroundColor = [UIColor blueColor];
UIViewController *root = // However you create your root.
window.rootViewController = root;
window.restorationIdentifier = NSStringFromClass([window class]);
self.window = window;
}
[self commonInitializationLaunching:launchOptions];
[self.window makeKeyAndVisible];
return YES;
}
Another gotcha to watch out for is to make sure that your UINavigationControllers and UITabBarControllers have restoration identifiers.
State restoration is generally integrated with storyboards. If you're using a storyboard, you should not be creating your own window, view controllers, etc. You should let the storyboard do this for you. What's happening is that the storyboard is doing all the state restoration, and then you're creating a new window and laying it on top of all that. If that's the case, you're probably creating two copies of your UI on every launch. You're just not noticing it.
If you are constructing your entire interface in code (not a recommended approach, but it does work), then you need to determine whether state restoration happened before creating your UI. This is fairly simple:
In your commonInitializationLaunching:, initialize only non-UI elements (things that wouldn't ever be in state-preservation). This is the place to handle things that the UI elements might rely on during state restoration. You don't have any of these in your current code.
In application:didDecodeRestorableState:, set an app delegate ivar to indicate that state was restored.
In application:didFinishLaunchingWithOptions:, after running commonInitializationLaunching:, check your ivar. If state wasn't restored, create a UI.
Do remember that the commonInitializationLaunching: pattern only exists for backward compatibility with iOS 5. If you don't need that, then just put non-UI in willFinish and UI in didFinish (if state wasn't restored).

presenting modal view from app delegate unbalanced calls to begin/end appearance

This is the code I'm using to present a modal view when the app first starts
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
Security *security = [[Security alloc] initWithNibName:#"Security" bundle:nil];
[self.tabBarController.selectedViewController presentModalViewController:security animated:YES];
[security release];
return YES;
}
This is what the log says
Unbalanced calls to begin/end appearance transitions for <UITabBarController: 0x171320>.
Is there a better way to achieve this?
Also I have this method in my app delegate
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if (viewController == [tabBarController.viewControllers objectAtIndex:2]) {
//The Log Out tab locks the app by presenting a modalviewcontroller that can't be dismissed unless there is a password.
Security *security = [[Security alloc] initWithNibName:#"Security" bundle:nil];
[self.tabBarController presentModalViewController:security animated:YES];
[security release];
return NO;
} else {
return YES;
}
}
Basically one of the options on my tabbarcontroller is a logout button. The above code works fine and doesn't throw a warning to the log.
Why are you presenting it from your tab bar controller? Assuming your above code is from a UIViewController, try
[self presentModalViewController:security animated:YES];
or
[self.navigationController presentModalViewController:security animated:YES];

Changing view from one xib to another xib with animation after some times

I have made a view based application which is loading a default view ...
My default view is a splash screen ..
What I want to achieve is once default view (splash view) finished loading, after few seconds it loads another view which is either a privacy policy or application screen.
Code in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
No Change as usual ...
Above code load a view from splashscreen.xib file
Following code is in splashscreen.m
- (IBAction)loadPrivacyScreen {
NSLog(#"Switching To Another View");
PrivacyPolicyView *modal = [[PrivacyPolicyView alloc]initWithNibName:nil bundle:nil];
modal.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:modal animated:YES];
[modal release];
}
- (void)viewDidLoad {
[super viewDidLoad];
sleep(3);
[self loadPrivacyScreen];
// Do any additional setup after loading the view from its nib.
}
After three second it does get in to the loadPrivacyScreen funciton but doesn't load the view.
- (IBAction)loadPrivacyScreen;
I have created a method as IBAction because I want to hook that method with a button on privacy screen to check that function works ...
And surprisingly it works when you click the button. But it doest work on time.
Can anyone suggest me what am I doing wrong ?? or any other alternative to achieve same thing??
Note: I have also try changing
- (IBAction)loadPrivacyScreen;
to
- (void)loadPrivacyScreen;
But still same result. It is not switching ....
First of all iOS provides a simple way to load a splash screen.
Just add a Image with 320x480 resolution in the name called default.png and add that to your project it will automatically use this image as splash screen image.
In your way call the loadPrivacy screen with a timer.
- (void)viewDidLoad {
[super viewDidLoad];
NSTimer *theTimer = [NSTimer scheduledTimerWithTimeInterval:3.00 target:self selector:#selector(loadPrivacyScreen) userInfo:nil repeats:NO];
}
- (void)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[viewController showSplash];
}
And in the view controller, define a method like
> IBOutlet UIView *modelView;
- (void)showSplash;
- (void)hideSplash;
-(void)showSplash {
UIViewController *modalViewController = [[UIViewController alloc] init];
modalViewController.view = modelView;
[self presentModalViewController:modalViewController animated:NO];
[self performSelector:#selector(hideSplash) withObject:nil afterDelay:2.0];
}
//hide splash screen
- (void)hideSplash {
[[self modalViewController] dismissModalViewControllerAnimated:YES];
}

Load an other View from applicationDidFinishLaunching in the AppDelegate

I have this code in my applicationDidFinishLaunching in the AppDelegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *firsttime = [defaults stringForKey:#"firsttime"];
if (firsttime == nil) {
BenutzerdatenViewController *Benutzer = [[BenutzerdatenViewController alloc] initWithNibName:nil bundle:nil];
Benutzer.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[Benutzer release];
[defaults setObject:#"lasttime" forKey:#"firsttime"];}
else { [window addSubview:viewController.view];
[window makeKeyAndVisible];}
Always when I open the app the first time I just see a with "view" instead of the right view with buttons and so on. Where is the problem?
You need to add the actual view to your window. For firsttime, you need the following:
[window addSubview: Benutzer.view];
Also, don't release that viewController; you should store a reference to it somewhere.
In the other case (!firstime), it's unclear where you're getting viewController from; I assume it's a member variable.