tableView didSelectRow not properly functioning - iphone

My other question was ambiguous so I will make this one clearer. I have a table view on one viewController and when a cell is selected, it saves a number to NSUserDefaults. On my main viewController, I retrieve this number and want to update a label with it. I did some debugging and found that when I go back to my main viewController from the tableView one, this is the order at what happens:
1) main view loads
2) tableView cell tap recognized
3) number saved to NSUserDefaults
How would I change the order so that the main view loads last so that when I click a cell, it changes the label in my main viewController?
Here is the code from my didSelectRow method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *pointsPath = [[NSString alloc] initWithFormat:#"totalPoints"];
NSString *numberFirst = [[NSString alloc] initWithFormat:#"numberFirst"];
int totalPoints = [[NSUserDefaults standardUserDefaults] integerForKey: pointsPath];
int number = [[NSUserDefaults standardUserDefaults] integerForKey:numberFirst];
if([indexPath row] == 1)
{
NSLog(#"Selected First row");
if(totalPoints < 10)
{
if (number != 0)
{
NSLog(#"Did not add a point, but saved");
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:numberFirst];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else if (number == 0)
{
NSLog(#"Added a Point");
int newPoints = totalPoints + 1;
[[NSUserDefaults standardUserDefaults] setInteger:newPoints forKey: pointsPath];
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:numberFirst];
[[NSUserDefaults standardUserDefaults] synchronize];
int logPoints = [[NSUserDefaults standardUserDefaults]integerForKey:pointsPath];
NSLog(#"Point Count:%i", logPoints);
}
}

A controller's view is loaded on demand. So the thing that triggers viewDidLoad is somebody else performing controller.view. If you've already pushed the view controller into a container view or otherwise started to present it then that'll be the agent responsible.
viewDidLoad, and under iOS 5 and below viewDidUnload, are intended to give you the hooks you need if you want to create some part of the view programmatically.
If what you're doing is trying to account for a setting that may have been changed while the controller wasn't visible, you should probably use viewWillAppear:. That's the intended way to determine when you're about to transition from invisible to visible.
If you wanted a completely active link between the two things then you would set up the view controller that displays the number to listen for NSUserDefaultsDidChangeNotification and to update views as necessary when that occurs.

Guys i finally found the problem if anyone has this problem... You need to make sure that when the user selects a cell, it is a push segue not a modal... This is so frustrating that is was so simple!!

Related

Creating a initial / first boot viewcontroller with NSUserDefaults in storybord

So im trying to skip my first viewcontroller if a NSUserDefaults key is found. But its not working. Is it smart to use a Segue for this? Im new to storybord.
Warning: Attempt to present on whose view is not in the window hierarchy!
Im using this code in the viewDidLoad of the first VC:
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"])
{
NSLog(#"not first launch");
[self performSegueWithIdentifier:#"SegueToNewTrackTraceVC" sender:self];
}else{
NSLog(#"First launch");
}
NSLog(#"initialViewController loaded");
}
You forgot to update the NSUserDefault after the first launch.
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"])
{
NSLog(#"not first launch");
[self performSegueWithIdentifier:#"SegueToNewTrackTraceVC" sender:self];
}
else
{
NSLog(#"First launch");
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"HasLaunchedOnce"];
}
You can't perform a segue from viewDidLoad, because the controller whose class that code is in, is about to be presented itself, and its view has not been added to the window hierarchy yet. You should put the code in viewDidAppearAnimated:. IF you don't want to see that segue happening, then uncheck the "Animates" box for the segue in the storyboard (that box is available for modal transitions, I don't think it is for a push).

Switching start up view controller Xcode

Say for example if I have two buttons one for apples and one for orange, and I select apples and takes me to the apples screen. How can I make it for now on every time I run the app it will go to the apples screen?
in viewDidLoad
if([[NSUserDefaults standardUserDefaults] objectForKey:#"fruit"] != nil)
{
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"fruit"]isEqualToString:#"apple"]) {
[self.navigationController pushViewController:appleVC animated:NO];
}
else{
[self.navigationController pushViewController:orangeVC animated:NO];
}
}
and on Button Methods
on Apple button
[[NSUserDefaults standardUserDefaults] setObject:#"apple" forKey:#"fruit"];
on Orange button
[[NSUserDefaults standardUserDefaults] setObject:#"orange" forKey:#"fruit"];
You can store information like this using NSUserDefaults.
You'd store a boolean bAppleSelected like this:
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setBool:bAppleSelected forKey=#"appleSelected"];
You can read it by accessing the default userDefaults:
BOOL bApple = [standardUserDefaults boolForKey=#"appleSelected"];
On your app delegate you must have some method that instantiates the very first controller and displays it in a window. You can just create an "apples controller" and push it there
You can use NSUserdefaults here,
NSString* fruit=#"apple";
[[NSUserDefaults standardUserDefaults]setObject:fruit forKey:#"controllerName"];
[[NSUserDefaults standardUserDefaults]synchronize];
and insted of the name string of your firstview controller in appdelegate file use the above NSUserDefaults.

iOS app sending an alert view only on the first time using the app

I would like to display an alertview when a user opens the app for the first time. After they open the app, they click on a button that pushes a table view on the navigation controller stack. If it's the first time the table view has ever been opened, there should be an alert view that displays telling the user that they can click the cell to edit.
How can I achieve this?
Thanks
Simply, use NSUserDefaults.
something like:
// the place where you want to check if this is the first run:
BOOL didRunBefore = [[NSUserDefaults standardUserDefaults] boolForKey:#"didRunBefore"];
if (!didRunBefore) {
// show alert;
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"didRunBefore"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
When your user taps on your button you should check for some value in [NSUserDefaults standardDefatults] if the check is nil you should display your alert and then save some value, so the next time you check for it, it would have some value stored and you do nothing.
Like this:
NSString * val = [[NSUserDefaults standardUserDefaults] objectForKey:#"kFirstTime"];
if (!val) {
//show alert
[[NSUserDefaults standardUserDefaults] setObject:#"1" forKey:#"kFirstTime"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//Your code

Do we always needs to dismissModelViewController that we had presented?

I have Edited whole Question
What is the difference between presenting the ModelView Controller and dismissing the modal view controller in following situation??
HomeView
TableItemSelection View
PickerView
In HomeView
I am writing code in viewWillAppear to fetch values from NSUserDefault that is set from TableView. Below is my code for viewDidLoad (for initial values) and viewWillAppear(when new value from tableview)
- (void)viewDidLoad
{
[super viewDidLoad];
actionMinutes = #"0";
actionSeconds = #"0";
restMinutes = #"0";
restSeconds = #"0";
}
- (void) viewWillAppear:(BOOL)animated
{
actionMin = [actionMinutes intValue];
actionSec = [actionSeconds intValue];
restMin = [restMinutes intValue];
restSec = [restSeconds intValue];
NSLog(#"acMin:%d acSec:%d reMin:%d reSec:%d",actionMin,actionSec,restMin,restSec);
}
In TableItemSelection View
I am presenting this view from HomeView. Now i want to set value of NSString in HomeView based on Table's didSelectRowAtIndex Method. I am using NSUserDefault to set the value.
And with Done Button touch i am presenting HomeView. (Actually I have to dismissModalViewController) But when i use dismiss I am not able to get values in NSString of HomeView. I am getting values of the table from PickerView. (I am instructed to do that). Below is my code for Table view on DONE button touch
HomeView *homeView = [[HomeView alloc] init];
[homeView.view setBackgroundColor:[UIColor clearColor]];
[homeView.view setFrame:CGRectMake(0 ,40, 320, 460)];
homeView.actionMinutes = [[NSUserDefaults standardUserDefaults] valueForKey:#"actionMinute"];
homeView.actionSeconds = [[NSUserDefaults standardUserDefaults] valueForKey:#"actionSecond"];
homeView.restMinutes = [[NSUserDefaults standardUserDefaults] valueForKey:#"restMinute"];
homeView.restSeconds = [[NSUserDefaults standardUserDefaults] valueForKey:#"restSecond"];
homeView.song = [[NSUserDefaults standardUserDefaults] valueForKey:#"songstring"];
NSLog(#"%#",homeView.actionMinutes);
[self presentModalViewController:homeView animated:YES];
//[self dismissModalViewControllerAnimated:YES]; // if this method is used then no values are passed to HomeView
[homeView release];
In PickerView
I am fetching the values from pickerview and then store it in UserDefault.
below is my code for pickerview
NSUserDefaults *actionTime = [NSUserDefaults standardUserDefaults];
[actionTime setValue:min forKey:#"actionMinute"];
[actionTime setValue:sec forKey:#"actionSecond"];
So why exactly i am not able to get UserDefault values when dismissing ModelView.??? Does presenting a new view everytime will make a stack of views???
#DShah: Yes most definitely..!!
You need to dismiss every modal view.
Also Please post the code you are using.
Also keep in mind that you need to put the NSUserDefaults line first (the line which you use assign NSString value to NSUserDefaults) and then put the line where in you dismissModalViewControllerAnimated:.
If you require more help please leave me a comment.
Hope this helps you.
I think you are trying to store integer value in NSUserDefaults then you have to
Use setInteger:forKey: instead of setObject:forKey:. An integer is not an object, it's a primitive type.
To retrieve it use integerForKey:.
This is the final answer through which i am able to solve my problem
Here is a code on Done button touch event...
- (IBAction) btnDonePressed:(id)sender {
aurioTouchAppDelegate *appDelegate = (aurioTouchAppDelegate *) [[UIApplication sharedApplication] delegate];
appDelegate.homeView.actionMinutes = [[NSUserDefaults standardUserDefaults] valueForKey:#"actionMinute"];
appDelegate.homeView.actionSeconds = [[NSUserDefaults standardUserDefaults] valueForKey:#"actionSecond"];
appDelegate.homeView.restMinutes = [[NSUserDefaults standardUserDefaults] valueForKey:#"restMinute"];
appDelegate.homeView.restSeconds = [[NSUserDefaults standardUserDefaults] valueForKey:#"restSecond"];
// [self presentModalViewController:homeView animated:YES];
[self dismissModalViewControllerAnimated:YES]; // if this method is used then no values are passed to HomeView
}

How to save Application State using NSUserDefaults in iPhone?

Following is what i am doing:
- (void) applicationWillTerminate: (UIApplication*) application {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:navigationController.viewControllers
forKey:#"diabetesstate"];
}
- (void) applicationDidFinishLaunching: (UIApplication*) application {
NSMutableArray *state = [[NSUserDefaults standardUserDefaults]
objectForKey:#"diabetesstate"];
if (state == nil) {
//Will initialize a new controller and put it as root view controller
}
else {
[navigationController setViewControllers:state animated:NO];
}
}
It looks like you're trying to add a UIViewController to the userdefaults? I doubt that will work.
I guess you'll have to put some identifer string or number in there that tells you which viewcontroller is currently displayed, and when the application starts basically check that value and set up your viewcontrollers accordingly.
I need to implement something similar for my application. I've got a list of objects, and when the user taps on one I am displaying a child object. My idea is to store the ID of the client object if one is currently being displayed, otherwise NULL. When the application starts I will check the value. If it's NULL I'll display the list of parent objects, otherwise I'll show the child object with the ID that's in userdefaults.