How to save a rating control value? - ios

I am playing around with DYRateView....a control at the end of a long list of controls I've tried out. It can be found here: https://github.com/dyang/DYRateView
The problem with all the controls I've tried is that I can't seem to save the rating once it's been changed. I'm using NSUserDefaults and have tried placing it in various places including where the value changes, where the view is set up, in viewDidLoad, in viewWillAppear, within the source code itself. Saving this value just has me flummoxed. I would appreciate any help. Just to get a sense of how this should work, I've just been working in the sample code that came with DYRateView. Here is the relevant code:
THE .M FILE
#import "DemoViewController.h"
#interface DemoViewController ()
- (void)setUpEditableRateView;
#end
#implementation DemoViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSUserDefaults standardUserDefaults] integerForKey:#"rating"];
[self setUpEditableRateView];
}
- (void)setUpEditableRateView {
DYRateView *rateView = [[DYRateView alloc] initWithFrame:CGRectMake(0, 40, self.view.bounds.size.width, 20) fullStar:[UIImage imageNamed:#"StarFullLarge.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge.png"]];
rateView.padding = 20;
rateView.alignment = RateViewAlignmentCenter;
rateView.editable = YES;
rateView.delegate = self;
[self.view addSubview:rateView];
[rateView release];
}
- (void)rateView:(DYRateView *)rateView changedToNewRate:(NSNumber *)rate {
self.rateLabel.text = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
[[NSUserDefaults standardUserDefaults] setInteger:rate forKey:#"rating"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#end
Thanks to anyone who takes the time!

You are trying to save an NSNumber as an NSInteger. You should do [[NSUserDefaults standardUserDefaults] setInteger:[rate integerValue] forKey:#"rating"]; or use - setObject:forKey: because NSNumber is an object, not a scalar.

You are getting rating valuea at: [[NSUserDefaults standardUserDefaults] integerForKey:#"rating"]; but what are you doing with this value?
I think that you need to get this value and set to DYRateView. So:
Create a property of DYRateView: #property DYRateView * rateView
Set it on setUpEditableRateView: self.rateView = [[DYRateView alloc] initWithFrame:CGRectMake(0, 40, self.view.bounds.size.width, 20) fullStar:[UIImage imageNamed:#"StarFullLarge.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge.png"]];
Update self.rateView (add it to end of setUpEditableRateView): rateView.rate = [[NSUserDefaults standardUserDefaults] integerForKey:#"rating"]

Related

Saving segmented controller position

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;
}

Getting the error "Unknown receiver coachMarksView; Did you mean WSCoachMarksView error?"

I'm currently implementing the WSCoachMarksView framework to introduce users to features when using the app for the first time. The code in my viewDidAppear however, gives me the following error: Unknown receiver 'coachMarksView'; Did you mean 'WSCoachMarksView'?
I'm not sure why this is happening, since I've instantiated coachMarksView already in viewDidLoad, so it should recognize it. Am I missing something?
- (void)viewDidLoad
{
[super viewDidLoad];
// Setup coach marks
NSArray *coachMarks = #[
#{
#"rect": [NSValue valueWithCGRect:(CGRect){{50,168},{220,45}}],
#"caption": #"Just browsing? We'll only notify you periodically of new matches. Need it soon? We'll notify you more frequently, and match you with items that are closer to you."
},
];
WSCoachMarksView *coachMarksView = [[WSCoachMarksView alloc] initWithFrame:self.navigationController.view.bounds coachMarks:coachMarks];
[self.navigationController.view addSubview:coachMarksView];
coachMarksView.animationDuration = 0.5f;
coachMarksView.enableContinueLabel = YES;
[coachMarksView start];
}
- (void)viewDidAppear:(BOOL)animated
{
// Show coach marks
BOOL coachMarksShown = [[NSUserDefaults standardUserDefaults] boolForKey:#"WSCoachMarksShown"];
if (coachMarksShown == NO) {
// Don't show again
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"WSCoachMarksShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Show coach marks
[coachMarksView start];
// Or show coach marks after a second delay
// [coachMarksView performSelector:#selector(start) withObject:nil afterDelay:1.0f];
}
}
You need to make coachMarksView a property so you can access the same instance. coachMarksView is undefined in viewWillAppear: because that scope has no knowledge of the scope in viewDidLoad.
To create a property for coachMarksView you need to do the following in your viewController:
#interface UIViewController ()
#property (nonatomic, strong) WKCoachMarksView *coachMarksView;
#end
and then in viewDidLoad
- (void)viewDidLoad
{
self.coachMarksView = [[WSCoachMarksView alloc] initWithFrame:self.navigationController.bounds]];
}
Now to access that instance just use self.coachMarksView.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.coachMarksView start];
}
Here is more info on getters, setters, and properties in Objective-C http://rypress.com/tutorials/objective-c/properties.html
You've declared coachMarksView as a local variable inside viewDidLoad. "Local" means it's only visible where you declared it.
Try changing it to a property of the class instead so that your object can access it from all of its methods. (Using self.coachMarksView.)

Not Updating Label From Different View Controller using NSUserDefaults

I am trying to update a label on view controller (DropPinVC) by pressing a button on different view controller 2 (TypeLocation).
In DropPinVC.m I have:
- (void)viewDidLoad
{
TypeLocation *VC2 = [[TypeLocation alloc] initWithNibName:#"TypeLocation" bundle:nil];
VC2.myVC2 = self;
[super viewDidLoad];
}
In TypeLocation.h I have:
#property (nonatomic, strong) DropPinVC *myVC2;
In TypeLocation.m I have:
-(IBAction) switchValueChanged
{
if (self.TASwitch.on){
TypeLocation = #"Tourist Attraction";
[[NSUserDefaults standardUserDefaults] setObject:TypeLocation forKey:#"Type Location"];
}
else {
TypeLocation = #"Unsafe Location";
[[NSUserDefaults standardUserDefaults] setObject:TypeLocation forKey:#"Type Location"];
DropPinVC *myVC2 = [[DropPinVC alloc] initWithNibName:#"DropPinVC" bundle:nil];
NSString *updatedLabel = [[NSUserDefaults standardUserDefaults] stringForKey:#"Type Location"];
NSLog(#"Updated Label = %#", updatedLabel);
myVC2.TypeLabel.text = updatedLabel;
[self closeScreen];
}
However, the label on view controller 1 does not update. Does anybody know a solution to this problem? Thank you for your help!
You need to pass the string, updateLabel, to a string property you create in DropPinVC, and have that controller populate its label in viewDidLoad. Your approach doesn't work because the view hasn't loaded yet at the time you try to set the label's text, so myVC2.TypeLabel will be nil.
Also, you're not using your property, myVC2 in TypeLocation. this line,
DropPinVC *myVC2 = [[DropPinVC alloc] initWithNibName:#"DropPinVC" bundle:nil];
should be,
self.myVC2 = [[DropPinVC alloc] initWithNibName:#"DropPinVC" bundle:nil];

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"];
}

How add values from text field / label to an array when a button click in iphone

I have a text field In that user can enter values from 1-10
at the bottom of the text field i have button.
i need to add the values in text filed to array when user clicks done button
for this i wrote code like this.
- (void)viewDidLoad
{
[super viewDidLoad];
PainlevelsArray = [[NSMutableArray alloc] init]; //PainlevelsArray declared in .h
}
-(IBAction)doneClick:(id)sender
{
[PainlevelsArray addObject:txtField.text ];
// [PainlevelsArray insertObject:rateLabel.text atIndex:0 ];
NSLog(#"PainlevelsArray *** %#",PainlevelsArray);
[self.navigationController popToRootViewControllerAnimated:YES];
}
But every time array displays only the recently added one value only in log when button clicks, like this
Output on Console
========================
2012-05-07 10:11:15.689 ESPT[796:10d03] PainlevelsArray *** (
2
)
2012-05-07 10:11:27.984 ESPT[796:10d03] PainlevelsArray *** (
4
)
My array gets empty every time view loads, and adde a fresh entry when button clicks
But i need like this
2012-05-07 10:11:27.984 ESPT[796:10d03] PainlevelsArray *** (
4,
5,
2,
6,
8,
)
All the velues enters are adde/inserted to the existing array.
Thanks in advance
in ExerciseStartViewController
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ExerciseResult *result = [[ExerciseResult alloc] init];
[self.navigationController pushViewController:result animated:YES];
[result release];
}
in current/ ExerciseResult viewcontroller
- (void)viewDidLoad
{
[super viewDidLoad];
PainlevelsArray = [[NSMutableArray alloc] init]; //PainlevelsArray declared in .h
}
-(IBAction)doneClick:(id)sender
{
[PainlevelsArray addObject:txtField.text ];
// [PainlevelsArray insertObject:rateLabel.text atIndex:0 ];
NSLog(#"PainlevelsArray *** %#",PainlevelsArray);
[self.navigationController popToRootViewControllerAnimated:YES];
}
You need to use a global array.
Best possible solution is declare an array in AppDelegate.h file and alloc-init this array in applicationdidfinishlaunch method.
AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[app.arrMutable addObject:textField.text ];
Use UserDefaults: These are used to save your application data in key-value format. The values/objects stored as userdefaults always remain in application, until you have not removed it from sandbox. You can use following code to store an array in userdefaults.
[[NSUserDefaults standardUserDefaults] setObject:app.arrMutable forKey:#"Global_Array_Key"];
In AppDelegae applicationDidFinishLuanch method you can retrieve this array from userdefaults using:
self.arrMutable = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:#"Global_Array_Key"]];
You need to declare and initialize PainlevelsArray globally, i.e. in AppDelegate or separate class of shared instance, where memory has been assigned once and it won't over write its data even though any number of time you access the said class and so that it will continuously inserts new value into the array and you will get the desired result.
ExerciseResult *result = [[ExerciseResult alloc] init];
[self.navigationController pushViewController:result animated:YES];
[result release];
I think you might be fallow this type of code in you action for coming to this view. Instead of this you have to fallow to take as global ExerciseResult *result
in .h
ExerciseResult *result;
in .m
in viewDidLoad
result = [[ExerciseResult alloc] init];
in you action method you will fallow
[self.navigationController pushViewController:result animated:YES];
you will follow like that
I hope it will helps you
Declare in Delegate.h page
#interface AppDelegate : NSObject <UIApplicationDelegate>
{
NSMutableArray *commString;
}
#property (nonatomic, retain) NSMutableArray *commString;
#end
Delegate.m page
#sythesize commString;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
commString = [[NSMutableArray alloc] init];
// some code.....
}
In your Button view
-(IBAction)doneClick:(id)sender
{
NSMutableArray *mut=[[NSMutableArray alloc] initWithObjects:txtField.text,nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.commString=mut;
// some code....
}
Declare this code where u want your array, you can easily get ur array.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"commString=%#",appDelegate.commString);
You use this line of code when you click just write add this line.
[array addobject:textfield.text];
use this only.
[PainlevelsArray addObject:txtField.text]
You should use properties for an array in this situation.
#property (nonatomic, strong) NSMutableArray *painlevelsArray;
Initialize the array
NSMutableArray *array = [[NSMutableArray alloc] init];
self.painlevelsArray = array;
Then add your string to the array after each button click
[self.painlevelsArray addObject:[NSString stringWithFormat:#"%#",self.textField.text]];

Resources