Saving segmented controller position - ios

I am facing an issue that my segmented controller is not saving its position after closing the application and opening it again.
My code is as per below:
- (void)viewDidLoad {
[super viewDidLoad];
[self.segmentedControlButtonStyle addTarget:self action:#selector(changeButtonStyle:) forControlEvents:UIControlEventValueChanged];
}
- (IBAction)changeButtonStyle:(id)sender {
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.number.application"];
NSInteger selectedSegmentedControlerIndex = self.segmentedControlButtonStyle.selectedSegmentIndex;
if (sharedDefaults) {
[sharedDefaults setInteger: selectedSegmentedControlerIndex forKey:#"MySelectedButtonStyleKey"];
[sharedDefaults synchronize];
}
}
The funny thing is that NSUserDefaults actually is saving correct index because from method I provided above if I change button style it will keep changed after closing and opening application again because I can see it by fact but segmented controller itself is not showing correct segment.
I am not sure why this is happening because I am synchronizing after each segment change but still segmented controller keeps its default position.

in view did load you should add code to set your saved segment
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.number.application"];
int mySegment = [sharedDefaults integerForKey:#"MySelectedButtonStyleKey"];
if(mySegment) {
self.segmentedControlButtonStyle.selectedSegmentIndex = mySegment;
}

Related

How to retrieve UISwitch state in each of my UITableView cells?

I have a UISwitch set as the accessoryView in each of my TableView cells.
If I press my Confirm button, I want to save the state of each UISwitch with NSUserDefaults. Then when I leave and go back to that View Controller, I should be able to load those saved states which will be different for each cell (either on or off, as shown in image).
I'm almost there but I guess I am not sure how to save/load with the right indexPath.row so it's not working correctly. Right now it is just saving/loading one BOOL value only, so if I save one cell with the switch ON, then all of them will be ON, and vice versa.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
BOOL menuSwitchState = [[NSUserDefaults standardUserDefaults] boolForKey:#"menuItemSwitch"];
NSLog(#"Menu Switch State is: %#", menuSwitchState ? #"Yes": #"No");
[self.switchView setOn:menuSwitchState animated:YES];
}
UISwitch code in my cellForRowAtIndexPath:
// Add a UISwitch to the accessory view.
self.switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = self.switchView;
self.switchView.tag = indexPath.row;
self.switchView.on = [[NSUserDefaults standardUserDefaults] boolForKey:#"menuItemSwitch"];
[self.switchView addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
Switch action method which sets a BOOL:
- (void) switchChanged:(id)sender {
UISwitch *switchControl = sender;
NSLog(#"The switch's tag number is %ld", (long)switchControl.tag);
// NSLog(#"The switch is %#", switchControl.on ? #"ON" : #"OFF" );
if ([sender isOn])
{
self.switchIsOn = YES;
NSLog(#"THE SWITCH IS ON");
}
else
{
self.switchIsOn = NO;
NSLog(#"THE SWITCH IS OFF");
}
}
Confirm button that should save the state of the switch:
#pragma mark - UIBUTTONS
- (IBAction)onConfirmMenuButtonPressed:(id)sender
{
[self performSegueWithIdentifier:#"segueMenuToGettingStarted" sender:self];
//TODO: Save state of Switch.
if (self.switchIsOn == YES)
{
[[NSUserDefaults standardUserDefaults] setBool:self.switchView.on forKey:#"menuItemSwitch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setBool:NO forKey:#"menuItemSwitch"];
}
}
You save that value just like any other value you use in a table view -- in an array that's your data source. Given what you show in your image, your data source should be an array of dictionaries with keys for the menu item, price, and switch state. In cellForRowAtIndexPath, you would set the state of the switch based on the value ( a BOOL) in your array.
in your code, you just set one NSUserDefault value for the all items(now, looks like three), I think you must separate each kind of item, it means you must have the count of NSUserDefault same as the count of UISwitch, In UIViewController, you can hold the NSUserDefault values in an Array, when you change the switch, you changed the cell data, when you leave the ViewController, save the Array's values. Enter the ViewController, update the Array.

UISegmentedControl Doesn't Deselect Old Segment

I have a UISegmentedControl in a UITableView Table row. The selection fires, and the new segment is highlighted. The problem is, the old segment remains selected.
If I close and reopen the popover that contains the table, the correct segment index is displayed.
I'm running XCode 6.1 and testing on iOS 7.1 simulator.
Assistance appreciated.
UITableViewCell *segmentCell = [tableView dequeueReusableCellWithIdentifier:segmentCellIdentifier];
if (segmentCell == nil) {
segmentCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:segmentCellIdentifier];
}
segmentCell.backgroundColor = [UIColor clearColor];
segmentCell.backgroundView = nil;
NSArray *segmentItems = [NSArray arrayWithObjects: NSLocalizedString(#"settingsBackgroundCork", #"Cork - Select cork background theme"), NSLocalizedString(#"settingsBackgroundDark", #"Dark - Select dark background theme"), NSLocalizedString(#"settingsBackgroundLight", #"Light - Select light background theme"), nil];
self.backgroundSegmentedControl = [[UISegmentedControl alloc] initWithItems: segmentItems];
[self.backgroundSegmentedControl addTarget:self action:#selector(backgroundControlChanged:) forControlEvents: UIControlEventValueChanged];
self.backgroundSegmentedControl.frame = CGRectMake(10, 6, 300, 32);
NSInteger background = [[NSUserDefaults standardUserDefaults] integerForKey:kUserDefaultsBackgroundSelection];
self.backgroundSegmentedControl.selectedSegmentIndex = background;
self.backgroundSegmentedControl.momentary = NO;
[segmentCell.contentView addSubview:self.backgroundSegmentedControl];
cellToReturn = segmentCell;
Here is the method that gets called on segment selection:
- (void)backgroundControlChanged:(UISegmentedControl *)control
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:control.selectedSegmentIndex forKey:kUserDefaultsBackgroundSelection];
self.backgroundSegmentedControl.selectedSegmentIndex = control.selectedSegmentIndex;
[self.backgroundSegmentedControl setNeedsDisplay];
[[NSNotificationCenter defaultCenter] postNotificationName:kPageBackgroundShouldChangeNotification object:nil];
}
Strange bug - I never saw this before. Two suggestions:
Try setting the selectedSegmentIndex again in the handler, and
Try calling setNeedsDisplay on the control there as well.
momentary is NO by default, so you should not need to set it.
Also, in the selectedSegmentIndex documentation it says:
The default value is UISegmentedControlNoSegment (no segment selected) until the user touches a segment. Set this property to -1 to turn off the current selection.
Maybe you want to try this last thing as well.
I was able to fix this issue by moving my call to setSelectedSegmentIndex to inside the setNeedsLayout function, instead of calling it right after creation of the UISegmentedControl. Of course I also had to create a variable to keep track of which segment should be selected.
Had the same issue. Resolved it by removing the previous instance of the segmentedControl from the superview before adding the new instance.
Adding the below-mentioned 3 lines of code to remove previous segmentedControl before adding the new instance of segmentedControl to the parent view.
self.backgroundSegmentedControl.tag = 101
if let foundView2 = segmentCell.contentView.viewWithTag(101) {
foundView2.removeFromSuperview()
}
[segmentCell.contentView addSubview:self.backgroundSegmentedControl];

Multiple UISwitch states not saved to NSUserDefaults from modal screen

I have a storyboard in my app with my UISwitch element (checklist) and I am attempting to store the switch states so that if the user checks a few items and then leaves the page (modally) or closes the app with the Home key, the state of the UISwitch elements is remembered and the user can continue along with the checklist.
If an item is read and you turn the UISwitch off, the font turns red else the UISwitch is on and the font is White.
Everything seems to work (still learning OOP and Xcode 5) except if I back out of the page (leave modally) and then return the UISwitch elements are all On again. If I stop the simulator (or IPAD) and restart the app when I get to the page all UISwitch are ON again instead of what was selected being OFF.
If I use the Home button and return to the app the UISwitch elements are still in the state they were left.
In the .m file here is the viewDidLoad method for just one of the switches:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
self.SwitchFlipChart.on = ([[standardDefaults stringForKey:#"Switch1"] isEqualToString:#"On"]) ? (YES) : (NO);
}
and below is the IBAction method for the same UISwitch element
- (IBAction)SwitchFlipchart:(UISwitch *)sender{
if (SwitchFlipchart.on) {
LabelFlipchart.textColor = [UIColor whiteColor];
} else {
LabelFlipchart.textColor = [UIColor redColor];
}
SwitchFlipchart.hidden = YES;
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if (sender.tag == 0) {
if (sender.on == 0) {
[standardDefaults setObject:#"Off" forKey:#"Switch1"];
} else if (sender.on == 1) {
[standardDefaults setObject:#"On" forKey:#"Switch1"]; //removed f from fSwitch1
}
}
[standardDefaults synchronize];
}
Does it appear I am using the NSUserDefaults correctly or is it because I am reloading the page when stopping the Simulator or leaving the Page Modally?
Is there a better (sometimes easier is not better) way to work with NSUserDefaults and multiple UISwitch elements?
Is there a better way to retain UISwitch element state when loading a page after leaving it modally?
Is there a better way to store UISwitch states than the NSUserDefaults?
Replace your code with this
- (IBAction)SwitchFlipchart:(UISwitch *)sender{
if (SwitchFlipchart.on) {
LabelFlipchart.textColor = [UIColor whiteColor];
} else {
LabelFlipchart.textColor = [UIColor redColor];
}
SwitchFlipchart.hidden = YES;
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if (sender.tag == 0) {
if (sender.on == 0) {
[standardDefaults setObject:#"Off" forKey:#"Switch1"];
} else if (sender.on == 1) {
[standardDefaults setObject:#"On" forKey:#"Switch1"];
}
}
[standardDefaults synchronize];
}
Explantion :-
You are setting on for wrong key. The key should be same Switch1 for both condition. But you are using fSwitch1 for On state. Please check your code.

How to keep UITextField text when the view changes

I've got two UITextFields, the input of which I store into strings player1 and player2. These UITextFields are on a ViewController called by a popOver segue. How can I make the UITextFields keep displaying their text once the view has changed?
I tried textFieldOne.text = player1; in the viewDidLoad section of the ViewController to no avail. Any ideas?
If your loaded view's delegate isn't ViewController, your code wouldn't be executed. So be sure that your code is on the delegate of the loaded view. Use also [textFieldOne setText:player1]. It's always better to call the setter method instead of setting the ivar directly. Then be sure that your UITextField is not nil and correctly binded. Use textFieldOne = [[UITextField alloc] init] to initialise it. If your problem continues, try also [textFieldOne setText:self.player1]. Hope it helps..
EDIT :
Got the solution here. You should use NSUserDefaults so your player names are stored and can be used in each view and even after re-opening your app (if you don't want this you can erase the defaults at lunch. Here is your bunch of code you need to change :
hardOne.m :
- (void)viewDidLoad
{
[super viewDidLoad];
[hard1ON setOn:switchState animated:NO];
//read player names to user defaults
[textFieldOne setText:[[NSUserDefaults standardUserDefaults] stringForKey:#"player1"]];
[textFieldTwo setText:[[NSUserDefaults standardUserDefaults] stringForKey:#"player2"]];
}
- (IBAction) returnKey1
{
player1 = [textFieldOne text];
[players addObject:(player1)];
//set player1's name to user defaults
[[NSUserDefaults standardUserDefaults] setValue:[textFieldOne text] forKey:#"player1"];
}
- (IBAction) returnKey2
{
player2 = [textFieldTwo text];
[players addObject:(player2)];
NSLog(#"array: %#",players);
//set player2's name to user defaults
[[NSUserDefaults standardUserDefaults] setValue:[textFieldTwo text] forKey:#"player2"];
}

don't show again ViewController

In my app, I created a first ViewController (in storyboard) called welcome, with all the instructions. At the end of the page, I wanted to insert a box that could be selected showing "don't show again". By clicking on this box, and going to the next page, the first viewController will vanish. When I reopen the app, the controller won't be shown again. The only way to show it is by going on settings and selecting the switch "repristinate original settings" or something like that. Please, can anyone help me? Thanks!
I found an example but is not what I want:
- (IBAction)leggi{
NSString *stringaTesto = campo.text;
testo.text = [[NSString alloc] initWithFormat:#"%#", stringaTesto];
NSString *testoInserito = testo.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:testoInserito forKey:#"ciao"];
[defaults synchronize];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *testoSalvato = [[NSUserDefaults standardUserDefaults] objectForKey:#"ciao"];
if (testoSalvato == nil) {
testo.text = #"Non hai ancora inserito il tuo nome";
} else {
testo.text = [[NSString alloc] initWithFormat:#"Ciao %#", testoSalvato];
}
}
The IB Outlet is linked to a button
store the don't show again as a BOOL in NSUserDefaults.. and check it before showing the view..
if it is TRUE..dont show.other wise show it.
edit
Lets say you have your app delegate and currently show your don't show view again (Lets say A) from it ..after which you show another view(Lets say B)
then in your app delegate you have to get a BOOL
like this
BOOL _Dont_Show_Again = [NSUSerDefaults standardDefaults] boolForkey : #"Don't Show"];
if(_Dont_Show_Again)
{
load B Code here...
}
else
{
load A Code here;
}
first time _Dont_Show_Again will be 0 since it does not exist in default..but if user select don't show you should save it in the default and this code will then work fine for you

Resources