Can I call presentModalViewController in viewDidLoad..? - iphone

In my iPhone app I have HomeViewController and ContentViewController. I am saving the values in ContentViewController by using NSUserDefaults
and based on saved values I will load the ContentView instead of HomeView when the app is restarted. if there r no values in the NSUserDefaults it displays the HomeView.
in HomeView I have some buttons..it's like this.. each button is for a book so in contentView all the page nos (in the bottom in a scroll view in ContentView) will be displayed if I click on a page no it displays the text in the above label of ContentView.if the user closes the app in contentView, the page no and book no will be saved...if the user clicks on home button all the information will be deleted.
In the Homeview im checking the NSUserDefaults, if it contains values it should display that exact page of that book
the following is the code...
//HomeViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
contentViewController = [[ContentViewController alloc] initWithNibName:#"ContentView" bundle:nil];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSLog(#"...%d,%d,%d",[prefs integerForKey:#"Stage"],[prefs integerForKey:#"Stimulus"],[prefs integerForKey:#"Card"]);
if(!([prefs integerForKey:#"Stage"] ==0 && [prefs integerForKey:#"Stimulus"] ==0 && [prefs integerForKey:#"Card"] ==0)){
[contentViewController setCurrentState:[prefs integerForKey:#"Stage"]];
[contentViewController setCurrentStimulus:[prefs integerForKey:#"Stimulus"]];
[contentViewController setCurrentCard:[prefs integerForKey:#"Card"]];
[self presentModalViewController:contentViewController animated:YES];
}
}
but it's displaying the homeview.

Try using the method viewDidAppear shown below instead of viewDidLoad
- (void)viewDidAppear:(BOOL)animated
{
contentViewController = [[ContentViewController alloc] initWithNibName:#"ContentView" bundle:nil];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSLog(#"...%d,%d,%d",[prefs integerForKey:#"Stage"],[prefs integerForKey:#"Stimulus"], [prefs integerForKey:#"Card"]);
if(!([prefs integerForKey:#"Stage"] ==0 && [prefs integerForKey:#"Stimulus"] ==0 && [prefs integerForKey:#"Card"] ==0))
{
[contentViewController setCurrentState:[prefs integerForKey:#"Stage"]];
[contentViewController setCurrentStimulus:[prefs integerForKey:#"Stimulus"]];
[contentViewController setCurrentCard:[prefs integerForKey:#"Card"]];
[self presentModalViewController:contentViewController animated:YES];
}
}

Related

Objective c. Login user using storyboard

I have an storyboard with three view controllers, the init view with a button Init, the login view controller and the list view controller. When I click in the button init in the first view controller, I would like to verify whether the user logged in in order to switch to the login view or to the list view. How could I implement this using segues (segue conditionals??)
You could do something like this
BOOL isLoggedIn = [[NSUserDefaults standardUserDefaults] boolForKey:#"isLoggedIn"];
NSString *headingStoryboardID = isLoggedIn ? #"YourAlreadyLoggedInVC_ID" : #"YourLoginVC_ID";
if([headingStoryboardID isEqualToString:#"YourAlreadyLoggedInVC_ID"]) {
AlreadyLoggedInClass *vc1 = (AlreadyLoggedInClass *)[self.storyboard instantiateViewControllerWithIdentifier:#"YourAlreadyLoggedInVC_ID"];
[self presentViewController:vc2 animated:YES completion:nil];
} else {
LoginViewController *vc2 = (LoginViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"YourLoginVC_ID"];
[self presentViewController:vc2 animated:YES completion:nil];
}
OBS: Ugly and uncompiled code but hope the concept gets across.
EDIT DUE TO COMMENT
To perform a push segue you call
[self.navigationController pushViewController:vc1 animated:YES];
instead.
You can Store your login value in user default when user login like this
in LOginViewController
-(void) doLogin
{
NSString * str = #"Loged In";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:str forKey:#"login"];
[defaults synchronize];
}
And in first view controller check whether this NSdefault value is nil or not.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *userLogIn = [defaults objectForKey:#"login"];
if (userLogIn.length !=0) {
//then user Loged in
}else
{
//then user not Loged in
}
This code is just example you can change it acording to your need.

NSUserDefaults Not Fully Working For Settings In App

I have a settings view in my app that will give the user the option of one of the Tabs showing either a feed of mp3s from a podcast or mov from a podcast. I set it up on the first time running the app to display an AlertView asking what they prefer. I do that with this in the applicationDidFinishLaunching:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (! [defaults boolForKey:#"notFirstRun"]) {
UIAlertView *firstrun = [[UIAlertView alloc] initWithTitle:#"Sermon Preference" message:#"Do you prefer audio only, or video sermons? (This setting can be changed at any time in the Settings Page.)" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Audio", #"Video", nil];
[firstrun show];
[firstrun release];
[defaults setBool:YES forKey:#"notFirstRun"];
}
Then I set this in the AppDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *nope = #"Audio";
[defaults setObject:nope forKey:#"videosermons"];
[defaults synchronize];
}
if (buttonIndex == 1) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *yup = #"Video";
[defaults setObject:yup forKey:#"videosermons"];
[defaults synchronize]; }
}
On the Root View (Which is the audio listing of sermons) of the Navigation Controller for sermons I set this in viewWillAppear:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *currently = [defaults objectForKey:#"videosermons"];
if ([currently isEqualToString:#"Video"]) {
self.videoView = [[[VideoPodcastTableView alloc] initWithNibName:#"VideoPodcastTableView" bundle:[NSBundle mainBundle]] autorelease];
[self.navigationController pushViewController:_videoView animated:NO]; }
if ([currently isEqualToString:#"Audio"]) {
}
I also set up a Settings Tab with a segmentControl to reflect what has been selected. This is the issue:
If I click on Video in the firstRun popup, and then go straight to the Sermons tab, it stays on Audio Sermons. I can then navigate to the Settings Tab and it will show Video selected. Now, without selecting anything, I can go once more to the Sermons tab, and it will now go to the Video Sermons. Why is it that it is not getting the message to change until after I go to the settings?
The problem is that you're already loading your root view before the UIAlertView clickedButtonAtIndex: selector is called. After you launch your UIAlertView in your AppDelegate, your application continues loading your root view in the background.
viewWillAppear will have already run by the time a UIAlertView option has been selected.
To solve this, I'd recommend having another root view as your initial view. If you're using storyboards, have one segue going to a view controller that launches your alert view, and another segue going to your tab page. On first launch, segue to the alert view page, and otherwise segue to the tab page. This way your NSUserDefaults #"videosermons" key can be set before the tab view is loaded.

IF statment not checking condition on first run

I'm new to programming and I have an app that has a login view on start up and request the user to enter their name which is used throughout out the program. Once they enter their name and log in they are presented with the main menu view. Their name is saved using NSUserdefaults.
The idea is that they will only have to login once (or again if they logout) so they should only see the login view the first time they run the app however once the app is started again it still shows the login screen and also you have to press the login button twice before you are taken to the main menu.
I know that the app is storing the details because it is used thought the app but I cant work out why. Here is my code. If someone could help it would be greatly appreciated.
-(IBAction)LogInButton:(id)sender
{
NSString *tempStr = [[NSUserDefaults standardUserDefaults] objectForKey:#"UserName"];
if(tempStr.length==0)
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:Name.text forKey:#"UserName"];
[prefs synchronize];
LogInView *Logview = [[LogInView alloc] initWithNibName:#"LogInView" bundle:nil];
[self presentModalViewController:Logview animated:YES];
}
else
{
MainMenuView *mainview = [[MainMenuView alloc] initWithNibName:#"MainMenuView" bundle:nil];
[self presentModalViewController:mainview animated:YES];
}
}
Judging by your description what you want is
On viewDidLoad check to see if the user is logged in
If YES show the MainMenu
If NO show the LogInView
The code may look like this
- (void)viewDidLoad
{
[super viewDidLoad];
[self showCorrectController];
}
The show correct controller method could look like this
- (void)showCorrectController
{
UIViewController *viewController = nil;
if ([self isLoggedIn]) {
viewController = [[MainMenuView alloc] init];
} else {
viewController = [[LogInView alloc] init];
}
[self presentModalViewController:viewController animated:YES];
[viewController release]; viewController = nil;
}
A convenience method is called isLoggedIn which looks like this
- (BOOL)isLoggedIn
{
// The double negation just means we get a boolean response
return !![[NSUserDefaults standardUserDefaults] objectForKey:#"UserName"];
}
Now edit your original method to something like this
-(IBAction)LogInButton:(id)sender
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:Name.text forKey:#"UserName"];
[prefs synchronize];
[self showCorrectController];
}
There are quite a few things that could be done to tidy this up a lot but this should be a start to get you going.
A word of caution on your naming of things. The convention is to start method and variable names with lowercased letters. Classes and constants start with uppercase letters.
It looks like the first time in:
The login screen shows up
The user presses login (and this method you're showing gets called)
The saved value isn't initially set, so this evaluates to true: if(tempStr.length==0)
You save the new value
You display another login screen
But I don't think you're showing all the code. What runs when the app launches?

NSuserdefaults not loading in a tab bar controller, works on uiview

I have a problem getting the NSUserDefaults to pull out on a tab/nav/tableview controller page, I've put the same code on a loginpage and the app will pull the objects for keys perfectly. I had this working when I had programmatically created the tabs and navs but now it's not working. The loginViewController is not in the tab stack, is that the reason it works?
-(void)refreshFields {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
usernameLabel.text = [defaults objectForKey:kUsernameKey];
passwordLabel.text = [defaults objectForKey:kPasswordKey];
}
- (void)viewDidAppear:(BOOL)animated {
[self refreshFields];
[super viewDidAppear:animated];
if ([usernameLabel.text length] == 0|| [passwordLabel.text length] == 0)
{
UINavigationController *loginNavigationController = [[UINavigationController alloc] initWithRootViewController:loginViewController];
[loginViewController release];
[self.navigationController presentModalViewController:loginNavigationController animated:NO];
[loginNavigationController release];
}
else
{
[[self tableView ]reloadData];
}
}
Your usernameLabel and passwordLabel outlets aren't set. Verify by putting a breakpoint in refreshFields.

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.