viewWillAppear and viewDidLoad for presenting login popup - iphone

I have a UIViewController in which it should pop up a LoginViewController if a user is not yet login. The question is where should I call this:
LoginViewController* lvc = [[LoginViewController alloc] init];
lvc.delegate = self;
//[lvc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:lvc animated:NO];
[lvc release];
should it be in the viewDidLoad or in the viewWillAppear? I guess it makes sense to put it in the viewWillAppear? I tried to put it inside the viewDidLoad and it gives me an extra border to the left and right of the view. Why is this?
UPDATE:
What I am trying to do here is to call presentModalViewController on the DetailViewController of a UISplitViewApplication. However nothing happens when I do so. I tried creating a new fresh project of a UISplitViewApplication and still it didn't work.
The question is why? and how do I present a modal view in the viewWillAppear of a UISplitViewApplication

The modal window tries to initialize itself with respect to the view controller that called it (resizing the nib, for example). Creating and displaying it in its parent's viewDidLoad can sometimes give it wrong information since the parent is still itself loading. This is why you are seeing discrepancies. Presenting the modal controller in viewDidAppear is better in this case since all the parameters are ready to pass to the modal controller so it can load its own view properly. Though sometimes if you have a lot to load, even that isn't enough and you will need to wait longer before you can present your modal view (which doesn't sound like your case at all, so there should be nothing to worry about there). I hope this helps, though

I would place something like this in the AppDelegate.
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
[self.window addSubview:self.viewController.view];
[self.window makeKeyAndVisible];
// Show the login screen if the user hasn't logged in yet
if (... login check here...)
{
LoginViewController* loginController = [[LoginViewController alloc] init];
[self.viewController presentModalViewController:loginController animated:NO];
[loginController release];
}
}
Your login screen will be placed on top of your normal viewcontroller. After a succesfull login dismiss the LoginViewController and your user can start using your app.

Related

UIViewController displayed behind current view when presented modally

On iOS 5, when I try to present any view controller from another one, using presentModalViewController, the modal view is presented behind the current view.
Since it works fine on iOS 4 and knowing that presentModalViewController has been deprecated in iOS 5, I tried using presentViewController with no luck.
This is the first time I encounter this issue, any ideas on what could lead to this weird behavior?
I believe the issue is that you have not set a proper modal presentation style.
http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UIModalPresentationStyle
This sample should trigger a full screen modal over top of your existing view controller.
[self setModalPresentationStyle:UIModalPresentationFullScreen];
ViewController2 *vc = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
[self presentViewController:vc animated:YES completion:NULL];
Not sure if you're using a button to present the view controller, but this should work if you are. Create a new function in your view controller like the one below. This instantiates your view and a navigation controller in your view so it can be dismissed afterwards.
- (void)buttonPressed {
UIViewController *yourViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navigationController = [[UINavigationController] alloc] initWithRootViewController:yourViewController];
[self presentModalViewController:navigationController animated:YES];
}
And then in viewDidLoad you'd have something like this (if you were presenting it from a button). The code below is for a UIBarButtonItem, but other buttons should work in a similar manner. Just make sure you set the action parameter to #selector(buttonPressed), or whatever the name of the function you want called when the button is pressed.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] init]
target:self
action:#selector(buttonPressed)];
I have finally found the issue. For some awkward reasons, the rootViewController of the root window wasn't set properly, leading to strange behaviors with modal views.
What is the more puzzling is that it worked fine on iOS 4 so far and failed on iOS 5. I believe I'm still missing the true reasons leading to such trouble, but correctly setting the rootViewController in AppDelegate solved the problem.

iPhone objective c how to choose which view controller to load at app start

I know there are quite a few threads about that topic, and I tried every single option. But nothing works.
So, here what I have, a loginviewcontroller and a tabbarviewcontroller. If the device is already registered, the tabbar should appear, if not the loginview. I have the tabbarviewcontoller as initial view controller in storyboard. This works if the device is registered.
This is what I basically do:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//define viewcontroller
LoginViewController *loginviewcontroller = [[LoginViewController alloc]init];
//check if device id in coredata
NSString *deviceId = [self retrieveFromUserDefaults:cKey_DeviceId];
if(deviceId == nil){
NSLog(#"device not registered");
[self.window setRootViewController:loginviewcontroller];
[self.window addSubview:loginviewcontroller.view];
}
//show them
[self.window makeKeyAndVisible];
return YES;
}
I have a NSlog output in my loginview viewdidload method, so I know, that the loginview is loaded. But the screen is black!!! I dont know why. The viewcontroller runs the viewdidload method, but there is just no screen output.
What do I do wrong???
thanks
dominik
If LoginViewController has a .xib file, you're calling the wrong init method. You want the initWithNibName:bundle: method.
Also, you do not need to call [self.window addSubview:loginviewcontroller.view]; after you set the root view controller.
And if the deviceId is NOT null, then you will get a blank screen.
And loginviewcontroller is leaking memory. You should release it after setting it to the root view controller.
In most cases using a password, I've found it's best to load the initial (already logged in) screen, then check to see if a login is needed. If it is, immediately put up a login screen as a modal view. Launch the login screen from viewDidLoad in your initial screen.

Presenting a ModalViewController inside a ModalViewController

I have a view which is presented as a modal view controller which takes username and password credentials. I want this view to check the delegate, and if the user hasn't previously set an unlock pin for the app, to then show the change pin view as a modal view controller. This is my code...
+(void)presentCredentialsViewController:(UIViewController *)vc{
CredentialsViewController *cvc = [[CredentialsViewController alloc] init];
[vc presentModalViewController:cvc animated:FALSE];
}
and then in CredentialsViewController
-(void)viewDidLoad{
[super viewDidLoad];
if([appDelegate.pin isEqualToString: #""]){
UserPrefsViewController *upvc = [[UserPrefsViewController alloc] init];
upvc.cancelButton.hidden = true;
[self presentModalViewController:upvc animated:FALSE];
}
}
But for some reason it doesn't work. The debugger steps through the code without error, never the less, the second modal view controller isn't displayed.
First, I would suggest checking that your appDelegate.pin is blank and not nil. If it is nil, the if statement would not be satisfied and your second ModalView would not be presented.
You may also want to try the previous suggestion, calling presentModalViewController from viewDidAppear, or setting a delay if leaving it in viewDidLoad. It is possible that the CredentialsViewController is trying to present the second view when it has not yet presented itself.
The if statement is being hit and the second PresentModalViewController is executing without error, but it just wasn't displaying. I did try putting the code in ViewDidAppear and a load of other places as well, such as applicationWillBecomeActive etc. Although not actually crashing the code, still none of these approaches would show the view controller. In the end I have opted for this:
start with pin of #""
on applicationDidEnterBackground check if pin has been set
if yes
PresentModalViewController: PinViewController
if no
do nothing
Bit of a hack but it will do for now. I suppose I should put some sort of notification in somewhere warning that the pin hasn't been set. The suggestion about the delay may possibly work I suppose. I might give it a go in the future. Thanks guys....points up!

Showing a modal view controller from a tab bar app

First, I would like to warn that I am a complete newbie into iPhone coding...
I need to show up a viewcontroller from a library, I know that it is modal. I have a tab bar app (created with the default XCode template). I need to show that viewcontroller, there are no problem if it hides the tabbar itself... But I am quite clueless, I don't know even what to search, or what to read...
You can call presentModalViewController:animated: to display another UIViewController modally.
EDIT: If you want to display your modal view in response to a button touch (for example), you would display it like this:
- (IBAction)buttonTouched:(id)sender
{
ModalViewController* controller = [[ModalViewController alloc] init];
[self presentModalViewController:controller animated:YES];
[controller release];
}
Then when you want to dismiss the modal controller, call dismissModalViewControllerAnimated:. This can be called either on your main view controller, or the modal one.
I don't know even what to search, or
what to read...
View Controller Programming Guide is a good place to start to help you understand view controllers (including modal ones). If that's confusing, get a bigger picture with iOS Application Programming Guide or start at the very beginning.
You can call modal view as
YourViewController *yvc = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:YES]
[self presentModalViewController:yvc animated:YES];
You can call it in the IBAction method in case you want to call it on any control event like Button Click
-(IBAction)buttonClicked:(id)sender
{
YourViewController *yvc = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:YES]
[self presentModalViewController:yvc animated:YES];
}
You can call it using self.
Hope this helps you.
If you have more doubts on this then you can ask me.

Add view to a navigation controller on app launch

I have an app that has a UITabBarController, one of the tabs of which is configured for a navigation controller.
Based on certain logic I need to attach a different root view to the navigation controller inside the tab at application launch time.
This is easily done in interface builder however, because I need to figure out what view to attach at launch time interface builder is not much use to me in this situation.
I'm guessing I will need to perform this in the applicationDidFinishLaunching method in my app delegate class by somehow getting the tab I'm interested in, and pushing the view onto it's navigation controller?
How would I go about this?
Thanks.
You're on the right track. In your app delegate's applicationDidFinishLaunching method, you need to look at whatever your condition is and pick the right thing to set as the UINavigationController's root view controller.
I'm guessing this is a login screen or something? And if you have a cached login from an earlier session you don't show it again? Is that it?
If you take a look at that method in your application delegate, you'll see where the default root view controller is getting instantiated and pushed into the nav controller. Just duplicate that code inside an if() statement. I've done this, it's straightforward.
So what I did in my applicationDidFinishLaunching method was:
// get the array of tabs
NSArray *tabBarArray = tabBarController.viewControllers;
// in my case the navigation controller I'm interested in is in the 4th tab
UINavigationController *navigationController = [tabBarArray objectAtIndex:4];
if(someLogic == true) {
ViewController1 *viewController1 = [[viewController1 alloc] initWithNibName:#"View1" bundle:nil];
[navigationController pushViewController:viewController1 animated:NO];
[viewController1 release];
}
else {
ViewController2 *viewController2 = [[viewController2 alloc] initWithNibName:#"View2" bundle:nil];
[navigationController pushViewController:viewController2 animated:NO];
[viewController2 release];
}
Everything working well.