Saving a UIScrollview with buttons to NSuserdefaults - ios

I have a scroll view full of buttons which are also in an NSMutableArray
how can i save the scrollview with the buttons so that they load in view did load.
I have a function that loads the buttons and places them into the scroll view and i have a function that removes the buttons. So it's the end state of the scrollview and its buttons needing to be saved.
If I can just save the array thats ok because I have a createButton function which takes in an NSString and creates a button in the scrollview and adds the object to the array so i suppose i could have 2 arrays but that hasn't worked and I'm fairly new so I think there is probably some really nice way to do this.
Thanks in advance!

Using NSUserDefaults, this is how you would do it. This is how you would save just one array:
[[NSUserDefaults standardUserDefaults] setObject:yourArray forKey:#"SavedArray"];
And then load it:
yourArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"SavedArray"];
Or you could save button locations and button titles separately:
To save...
[[NSUserDefaults standardUserDefaults] setObject:titlesArray forKey:#"Titles"];
[[NSUserDefaults standardUserDefaults] setObject:locationsArray forKey:#"Locations"];
And to load...
titlesArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"Titles"];
locationsArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"Locations"];
NSUserDefaults are actually very cool how simple they are. I hope this has helped.

Related

How do I save the text that the user enters into a UITextView

I am basically making a simple notes application. In myViewController I have a UITextView. I want the text that the user types in the UITextView to be saved so that the next time the user opens the app it is still there. How would I go about doing that? I want it to save onto the device so they can type and save a large amount of text.
You could save it easily using NSUserDefaults too.
Add this line of code in your button save event or can add it in your UITextViewDelegate method textViewDidEndEditing: But don't forget to assign delegate of textview using
textView.delegate = self;
Now to store use following code:
NSString *valueToSave = textView.text;
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"preferenceName"];
[[NSUserDefaults standardUserDefaults] synchronize];
And to retrieve it back later, use this in your viewDidLoad: or viewWillAppear:
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferenceName"];
textView.text = savedValue;
Hope it helps.. :)
There are several mechanisms available from iOS for storing data. Which one makes sense for you depends on the size and type of data you want to store and how you need to be able to use it.
A simple place to start might be NSString's writeToFile: (and also Where You Should Put Your App’s Files).

Contents of NSArray saved in NSUserDefaults gets overwritten whenever the view controller is called

A View Controller contains:
UITextField(Name).
UIButton(save).
Once I type any name and hit save, The name is added to an array which is stored using NSUserDefaults.
This View Controller is pushed from another View Controller and so when I go and come back to this View Controller, the contents of NSArray gets overwritten with the new names that i might specify. I'm not sure whats causing this but i'm suspecting that it has to do something with allocation and initialization of NSArray.
In my ViewDidLoad, I did NSMutableArray *namesList= [[NSMutableArray alloc]init];
And in my OnSave method,
[namesList addObject:nameTextField.text];
[[NSUserDefaults standardUserDefaults] setObject:namesList forKey:#"namesListArray"];
NSLog(#"items in array: %#",namesArray);
EDIT:
Screenshot of related View Controllers:
Here, when i click the ADD button, the second View Controller is pushed.
When i enter "kenneth" and hit save, the console says:
2014-03-03 11:03:46.219 SmartWatch[664:a0b] items in array: (
kenneth)
Now, without going back to the previous View Controller ,when i type another name say,"john" and hit save, the console says:
2014-03-03 11:15:43.646 SmartWatch[664:a0b] items in array: (
kenneth,
john)
Until now everything is good.
The problem occurs when i go back to the previous Controller and come back to the second View Controller.Now, when i type another name ,say "scott",the console says:
2014-03-03 11:19:50.815 SmartWatch[664:a0b] items in array: (
scott)
This means that the previous two names were overwritten. I want the array to retain "kenneth" and "john" too and "scott" should actually be appended to the array.
I think this happens because the array gets initialized when the second View Controller comes to the foreground again but I'm not sure of it and i dont know how to rectify this.
Hope the question is clear now. Thanks!
Try this,
NSArray *nameArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"namesListArray"];
NSMutableArray * namesList;
if (!nameArray) {
namesList = [[NSMutableArray alloc] init];
} else {
namesList = [NSMutableArray arrayWithArray:nameArray];
}
On save
[namesList addObject:nameTextField.text];
[[NSUserDefaults standardUserDefaults] setObject: namesList forKey:#"namesListArray"];
[[NSUserDefaults standardUserDefaults] synchronize];
Make your nameList array as a property and in viewDidLoad
self.namesList = [[[NSUserDefaults standardUserDefaults] objectForKey:#"namesListArray"] mutableCopy];
if (nil == namesList)
{
self.namesList = [[NSMutableArray alloc]init];
}
onSave method
[self.namesList addObject:nameTextField.text];
[[NSUserDefaults standardUserDefaults] setObject:self.namesList forKey:#"namesListArray"];
Whether you are doing any functionality to store elements to nsarray in ViewWillAppear Method.If not please specify your code properly to help!
Add [[NSUserDefaults standardUserDefaults] synchronize]; at end of NSUserDefaults. Other wise problem is else where, you need to to put relevant code with output of NSUserDefaults.

How do I initialize a segmented control with a value from NSUserDefaults

My UISegmentedControl will not stay selected. I have made sure that momentary is NO. So the solutions I have come across on here have not helped.
Would someone please be able to point me in the right direction?
EDIT
Thought I might make this question a bit clearer.
I have a UISegmentedControl and it has four selections (10,20,30,40) which changes the amount of questions asked on my quiz page. Making a selection works fine and changes the amount of questions.
But when I leave that view and go back later on to change the amount of questions again, it shows the selected as 10 even if I have selected something else.
How can I keep it showing the actual selected value?
EDIT
The number of questions is saved in NSUserDefaults.
[[NSUserDefaults standardUserDefaults] setInteger:amountOfQuestions forKey:#"Amount"]
How do I initialize a segmented control with a value from NSUserDefaults?
EDIT - Solved
#SettingsViewController .m file.
- (void)viewDidLoad
{
amountOfQuestions = [[NSUserDefaults standardUserDefaults] integerForKey:#"Amount"];
if (amountOfQuestions == 10) {
mySegment.selectedSegmentIndex = 0;
}
I did not have the below code in my IBAction for my segmented control. So when i tried the above code it did not work. Now it works a treat.
[[NSUserDefaults standardUserDefaults]synchronize];
#SettingsViewController .m file.
- (void)viewDidLoad
{
amountOfQuestions = [[NSUserDefaults standardUserDefaults] integerForKey:#"Amount"];
if (amountOfQuestions == 10) {
mySegment.selectedSegmentIndex = 0;
}
I did not have the below code in my IBAction for my segmented control. So when i tried the above code it did not work. Now it works a treat.
[[NSUserDefaults standardUserDefaults]synchronize];

Programming a button press in one view controller, to load and save a cell in a different table view controller

In my application I have a number of view controllers, all of which have a favorite button on. When the favorite button is pressed, I want some information about the view controller to be saved in a separate table view in a different table view controller.
This is my first IOs app, and even after reading about Core Data, I'm at a bit of a loss as to how to go forwards.
How would I go about implementing such a feature?
Thanks for helping a novice out!
Cheers.
To store information locally you can use the NSUserDefaults class.
On the favorite button action method, save the viewcontroller name in an NSMutableArray using NSUserDefaults
-(IBAction)btnFavouriteClick:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Get favorited views array (new array will be created if it doesn't exist)
NSMutableArray *favoriteviews = [defaults mutableArrayValueForKey:#"favorite_views_key"];
//Add current view name to the array
[favoriteviews addObject:#"viewcontroller_name"];
//Add the array back in NSUserDefaults
[defaults setObject:favoriteviews forKey:#"favorite_views_key"];
//Save NSUserDefaults
[defaults synchronize];
}
You can retrieve the values using favorite_views_key and show them in the UITableView
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Get favorited views array
NSMutableArray *favoriteviews = [defaults mutableArrayValueForKey:#"favorite_views_key"];
favoriteviews is array of all the favorited views.

iOS NSUserDefaults loads slow

I am using NSUSerDefaults to store a couple strings and integers for my application. Whenever a view is opened, the string is loaded slower than the view so you see a glitch. For example, I save the selectedSegmentIndex and then read it in viewDidAppear and for a quick moment when the view is called, no segment is selected, then the right one selects. How do you make it so there is no time gap between the view being opened and the setting be read?
- (void)viewDidLoad
{
[super viewDidLoad];
int segmentIndex = [[NSUserDefaults standardUserDefaults] integerForKey:#"selectedIndex"];
unitSegmentControl.selectedSegmentIndex = segmentIndex;
BOOL location = [[NSUserDefaults standardUserDefaults] boolForKey:#"locationManager"];
[gpsSwitch setOn:location animated:NO];
deviceID.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"DeviceID"];
}
- (IBAction)changeSeg:(id)sender {
if (unitSegmentControl.selectedSegmentIndex == 0) {
[[NSUserDefaults standardUserDefaults] setObject:#"http://98.246.50.81/firecom/xml/units/E01.xml" forKey:#"parserURL"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Main" forKey:#"selectedStation"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Fire & Rescue" forKey:#"selectedDepartment"];
}
if (unitSegmentControl.selectedSegmentIndex == 1) {
[[NSUserDefaults standardUserDefaults] setObject:#"http://98.246.50.81/firecom/xml/units/E02.xml" forKey:#"parserURL"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Witch Hazel" forKey:#"selectedStation"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Fire & Rescue" forKey:#"selectedDepartment"];
}
[[NSUserDefaults standardUserDefaults] setInteger:unitSegmentControl.selectedSegmentIndex forKey:#"selectedIndex"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
The defaults are not slow, you’re just loading the data too late. The standard place to populate views is in -viewDidLoad or -viewWillAppear in the view’s controller. Both will update the view soon enough to avoid visual glitches. If any of the two doesn’t work for you, here’s some tips to find the reason:
Try to set the selected index to a hard-wired number. This will tell you if the problem is in the defaults or (much more likely) in the -setSelectedSegmentIndex call.
Move the UI population code to -viewWillAppear. That’s the latest moment to update the UI before it’s displayed.
Use NSParameterAssert to make sure unitSegmentControl is not nil.
Make sure the index read back from the defaults is the expected number. Generally, it’s best to pull the defaults keys into constants. That way you can’t bump into simple typo bugs:
static NSString *const SelectedSegmentKey = #"selectedSegment";
If everything else fails, use a custom UISegmentControl subclass for your unitSegmentControl and place a breakpoint into -setSelectedSegmentIndex to see who else might be calling it.

Resources