I don't know how to do something with a number (see inside) - uibutton

I have in my app a label and a button.
The label has the number 20.
every I click the button the number decreases in 1.
I set the stating number (20) on view did load.
the problem is that when i leave the app it sets it back to 20.
and i want to return to the number I left the app at.
what to do ? where to set the starting number?
I am using Xcode and objective c.

When you need to save the number:
[[NSUserDefaults standardUserDefaults] setInteger:number forKey:#"key"];
[[NSUserDefaults standardUserDefaults] synchronize];
Then when you need to set number for label:
number = [[NSUserDefaults standardUserDefaults] integerForKey:#"key"];
label.text = [NSString stringWithFormat:#"%d", number];

Related

Objective-C: For Loop Variable Name

I have made an app that shows a todo-list for certain days. There are five labels that display a string that's been saved using NSUserDefaults. The code looks something like this:
monday1.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"mo1"];
monday2.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"mo2"];
monday3.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"mo3"];
monday4.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"mo4"];
monday5.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"mo5"];
There are a lot of those lines in my code and it takes up a lot of space. I wanted to make the code shorter.
Notice that in every line the key increases by one and the label title also increases by one. You can use a for loop with the objectForKey part but not with the label title. Or at least, that's what I thought. It would make my code a lot cleaner if I could just write something like this:
for(int i = 0; i < 5; i++)
monday-%i.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"mo%i", i];
I have tried to find a way to do this but I can't find anything online. There are no sites that say how to do it, but on the other hand there are also no sites that say it's impossible.
So does anyone know how to do this? Or is it impossible? Or any alternatives?
You can’t build variable names at runtime.
As the variables represent outlets my suggestion is to use an array.
NSArray<NSTextField *> *labels = #[monday1, monday2, monday3, monday4, monday5];
for(int i = 0; i < 5; i++) {
labels[i].stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"mo%i", i+1]];
}
Alternatively declare the labels as IBOutletCollection which creates the array on Interface Builder level.

Obj-C - NSString that saves all input using currentTitle and UILabel.text methods

NSString* digit = [sender currentTitle];
if (self.userIsInTheMiddleOfEnteringANumber){
NSString* currentDisplayText = [[self display]text];
NSString* newDisplayText = [currentDisplayText stringByAppendingString:digit];
self.display.text = newDisplayText;
I´ll try and explain my problem as good as I can. This line of code here takes the digit from a selection of buttons, saves it no the string "digit". "currentDisplayText"takes the digit displayed in a label. Then these two strings are appended and sent to the "display" (label)
But there is also an enter button. Which clears the display (so user can enter new number ) this is a calculator btw!
- (IBAction)enterPressed{
[self.brain pushOperand:[self.display.text doubleValue]];
self.userIsInTheMiddleOfEnteringANumber = NO;
What I want is to display a "history" label that displays all the numbers entered - I have not quite understood how I get the string I save the "history" too, to not reset like the display does. This might be bad exlained by me, but any hints are appreciated. I am still learning objective-c...
If I understood you correctly, you want to save the number after pressing the enter button. For this you need to add an attribute of type NSMutableArray to your class. Then in the method do:
- (IBAction)enterPressed {
[myHistoryArrayAttrib addObject: self.display.text];
[self.brain pushOperand:[self.display.text doubleValue]];
self.userIsInTheMiddleOfEnteringANumber = NO;
//after this you can clear your display
self.display.text = nil;
}
That's it.
I did not understander you very well , but one thing I am sure , if you want save your data (not very large) , you should use NSUserDeafult . use - (void)setObject:(id)anObject forKey:(id)aKey;to save the data.
You want to svae the history , if you want to save the lastest history , you could use - (NSString *)stringForKey:(NSString *)defaultName; to get the string which you save. and if you want to save the whole history , you could use - (NSArray *)arrayForKey:(NSString *)defaultName; to get the array which you save.
give an eg. how to save a string
if([[NSUserDefaults standardUserDefaults] stringForKey:theKey] == nil)
{
NSString *defaultValue = [NSString stringWithString:theStringYouWantedSave];
NSDictionary *saveDict = [NSDictionary dictionaryWithObject:defaultValue forKey:theKey];
[[NSUserDefaults standardUserDefaults] registerDefaults:saveDict];
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:theStringYouWantedSave forKey:theKey];
}
and get like this
if([[NSUserDefaults standardUserDefaults] stringForKey:theKey]!=nil)
{
yourHistoryString = [[NSUserDefaults standardUserDefaults] stringForKey:theKey];
}

How to initialize and accumulate the integer value when I change views?

I have 2 views first view to keep and accumulate integer value to move my image.
The second view to generate the random number and send it to the first view to accumulate the value each time switching between these 2 views.
First view .h
int move;
First .m
// to get random value and accumulate value
-(void)getMovepoint:(int)number{
moveValue += number;
}
// to move my image
- (void)viewDidLoad{
double xPos;
double yPos;
xPos = [[P1XArraypos objectAtIndex:moveValue]intValue];
yPos = [[P1YArraypos objectAtIndex:moveValue]intValue];
image.center= CGPointMake(xPos,yPos);
Second view .h
int randomMove;
Second view .m
randomMove = arc4random() % 6+1;
[board getMovepoint: randomMove];
Question.
First - I want to initialize the moveValue = 0 so the array will start at first index. I just don't know where to put it and make it will not re-initialize moveValue back to 0 again when the view is changing back.
Second - Each time i switch view to generate random value and switch back to the first view. How can I make it accumulate to the previous value?
Please help.
Thanks you.
ps. I'm very sorry if there is any bad grammar. It's not my native language.
Just use NSUserDefaults to store the value and then read it, increment and save it again in each view.
You can then reset it on ApplicationLaunch if needed.
Example (Setting):
// Increment your number or whatever
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSNumber *randomMoveObj = [NSNumber numberWithInt:randomMove];
[prefs setValue:randomMoveObj forKey:#"randomMove"];
[prefs synchronize];
Example: (Getting):
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSNumber *randomMoveObj = [prefs valueForKey#"randomMove"];
NSInteger *randomMove = [randomMoveObj intValue];
// Do something with the number
Initialize in ViewDidLoad.
Do you have it successfully switching between views? In the code that triggers that action, you can increment the variable.

How to calibrate UIAccelerometer?

I am trying to calibrate my UIAccelerometer from ViewA but my Game view is ViewB. So pretty much what I want to achieve is lets say the user is playing on their side, I want my game to act like if they were playing while sitting up in a normal position.
So in ViewA would I do something like so?:
float accelX = (acceleration.x - [[NSUserDefaults standardUserDefaults] floatForKey:#"value1"]);
[[NSUserDefaults standardUserDefaults] setFloat:accelX forKey:#"value1"];
Then in my Game class would I do this in my UIAccelerometer delegate method?:
float accelX = (acceleration.x - [[NSUserDefaults standardUserDefaults] floatForKey:#"X-Calibrate"]);
//Low Pass Filter
rollingX = (accelX * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
AccelPoint.x += (rollingX*50);
Then I would do something like:
mySprite.position = ccp(accelX, yValue);
Am I doing anything wrong?
Thanks!
Edit: New code for ViewB, will I still need some form of friction now?
rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
AccelPoint.x += (rollingX*50);
Then after that code I would set the position of my object.
The example in this question appears to be calibrating in a similar manner to what you've described: Accelerometer & Calibration - iPhone SDK
Your example code for View A:
float accelX = (acceleration.x - [[NSUserDefaults standardUserDefaults] floatForKey:#"value1"]);
[[NSUserDefaults standardUserDefaults] setFloat:accelX forKey:#"value1"];
This will be storing a pre-calibrated value. So the effect of the calibration will be minimised if you've ever calibrated before.
I think just:
[[NSUserDefaults standardUserDefaults] setFloat:acceleration.x forKey:#"value1"];
Might be more what you're after. This way you'll be removing the entire effect of gravity in the user's starting position.
Your code for View B seems fine, although bear in mind this will allow the speed of your character to increase indefinitely. Consider adding some form of friction.

How to do it can limit the number of open app?

I have a program on which you want to limit the number of functions.
For example: send a message function can only be used 10 times, can not be used up in the open, and will pop up the number of your purchase information.
I have tried using the following method can be successful from 10 -> 0, but close the program to reload after the value has changed back to 10 up!!
There is no way 10 -> 0, close the program after re-loading or 0?
Thank you!!
- (void)viewDidLoad {
[super viewDidLoad];
numberoftimes = 10;
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
[def setInteger:numberoftimes forKey:#"IntegerVal"];
[def synchronize];
numberoftimes-= 1;
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
[def setInteger:numberoftimes forKey:#"IntegerVal"];
[def synchronize];
It looks to me like you are setting the value of #integerVal to 10 every time your viewDidLoad method is called. What you want to do is get the existing value before you decrement it...
int currentNumberOfTimes = 10;
if ([def valueForKey:#"integerVal"]) {
currentNumberOfTimes = [[def valueForKey:#"integerVal"] intValue];
}
numberOfTimes = currentNumberOfTimes --;
[def setInteger:numberoftimes forKey:#"IntegerVal"];
[def synchronize];