I have a UITableview with custom cells in it. One of the customcell has a UISWITCH in it. When the scroll the table view the state of the switch gets reset even if I set it to ON. How can I maintain the state of the switch during scroll. Any help is appreciated.
-(IBAction)sameDriver:(id)sender{
if ([sender isOn]){
NSLog(#"%#",(otherdriver.drive ? #"YES" : #"NO"));
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool: YES forKey: K_SWITCH_KEY];
[defaults synchronize];
Switchon = [defaults boolForKey: K_SWITCH_KEY];
if(Switchon){
otherdriver.dfname.text = fname;
otherdriver.dlname.text = lname;
otherdriver.demail.text = email;
otherdriver.dpnum.text = phone;
}
}
else if(![sender isOn]){
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool: NO forKey: K_SWITCH_KEY];
[defaults synchronize];
NSLog(#"%#",(otherdriver.drive ? #"YES" : #"NO"));
Switchon = [defaults boolForKey: K_SWITCH_KEY];
otherdriver.dfname.text = drfname;
otherdriver.dlname.text = drlname;
otherdriver.demail.text = dremail;
otherdriver.dpnum.text = drphone;
}}
i am setting the UISwitch in IB. It is inside a custom UITableviewcell.
Thanks
In your header file, declare an NSString to hold the status of the switch.
Let's name it theSwitchPosition.
Then, in your method which runs when the switch is triggered, make theSwitchPosition hold the status of the switch:
theSwitchPosition = [NSString stringWithFormat:#"%#", switchControl.on ? #"ON" : #"OFF"];
After that, in the method where you create the UISwitch, set the switch's status based on the string that holds the data:
if ([theSwitchPosition isEqualToString:#"ON"]) {
mySwitch.on = YES;
} else {
mySwitch.on = NO;
}
This will work if you have only one UISwitch in your table view. If you have more than one, you need to use NSMutableArray instead.
I assume you're saying that if you scroll down (switch cell gets scrolled off screen), and then you scroll back up (switch cell gets scrolled back on screen) then the state of the switch isn't preserved. Is this correct?
If so, I would guess the issue is that the cell is being recycled and recreated. This happens when you get your cell from dequeReusableCellWithIdentifier:CellIdentifier. To fix this, you will need to give your special cell a different CellIdentifier.
If this is still unclear, please paste your code for tableView:cellForRowAtIndexPath: and I will try to help you further.
Related
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.
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.
i have created a settingsView and also a view that gives you a choice to be notified if you want at a certain time its a yes or no but i do not know how to access the value of the uiswitch i know instead of trying to get the views object i should try the preference that the state has been saved to but i don't know how i just want to tap my UISwitch and then in the settingsView the UILabel gets filled but i don't know how to access the value on the UISwitch once tapped i have saved it in NSUserDefaults in the notifiedView but do not know how to access that value in the settingsView so i can put in the settingsView
if (UISwitch.on)
{
//notify me please
} else {
// leave as is
}
of course that's just a quick layout of how i want it to be though and also where do i put the it in the settingsView viewDidLoad, viewWillAppear or both please help im a new be as well so please be kind if i have said things that you would deem not the right syntax thanks
Try this code:
// add this code in your switch touch event
- (IBAction)YourSwitch:(UISwitch*)sender
{
if (UISwitch.on)
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:true forKey:#"Sound"];
[defaults synchronize];
}
else
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:false forKey:#"Sound"];
[defaults synchronize];
}
}
Add this code in your viewdidload .
BOOL swithState = [[NSUserDefaults standardUserDefaults] boolForKey:#"Sound"];
if (swithState)
{
_ref_slider.on=true;
}
else
{
_ref_slider.on=false;
}
i hope this code is useful for you.
Just make a UISwitch property in your UIViewController and make sure you set it in the init/viewDidLoad of your class (from an IBOutlet or when you programmatically add it to your view). Then you can access the on-property of the UISwitch from anywhere within your class (and a load of extra features!) and use the if-statement as you want..
Apple Doc ref: https://developer.apple.com/library/ios/documentation/uikit/reference/UISwitch_Class/Reference/Reference.html
If your are using storyboard then hook up your UISwitch's action and write the below code in it.
- (IBAction)switchTapped:(id)sender
{
if ([sender isOn]) {
// your code
}
else
{
// your code
}
}
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
I am making a utility application, and I have a label on my main view. Depending on the user's selection, that label should say one of two things. How can I use a segmented control to change the label text?
In your flipside, create an IBAction called segmentedControlChanged - and hook it up to the 'value changed' trigger on the segmented control.
At the top of your settings controller, declare this constant:
#define kSegmentKey #"SegmentSetting" // Call these whatever you want
In your segmentedControlChanged method, write to NSUserDefaults, like so:
- (IBAction)segmentedControlChanged:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:[sender selectedSegmentIndex] forKey:kSegmentKey];
}
In your main view controller's viewWillAppear, put the following code:
- (void)viewWillAppear:(BOOL)animated {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int setting = [defaults integerForKey:kSegmentKey];
if (setting == 0) {
myLabel.text = #"First Message";
}
else {
myLabel.text = #"Second Message";
}
}
You can:
(1) store the segmented control's value in a variable that's passed as a return value to the FlipsideViewControllerDidFinish method, or else
(2) store the value in some area accessible to both the Flipside view and the First view, such as [NSUserDefaults standardUserDefaults].