Storing integers in an IBAction and passing them to another IBAction - ios

I have a pause IBAction & a resume IBAction, both for buttons, but I have game points I collect over the duration of the game play. How can I store the different game points integer values in the pause IBAction & pass them to the resume IBAction method.
NOTE: The pause IBAction invalidates all the NSTIMERS, and the resume IBAction recreates them.

Just to assist, I found a quick solution....but I'm sure there's a cleaner method:
In the vc.h:
NSMutableArray storeVariables;
In the vc.m
int a, b, c, d;
- (void)viewDidLoad
{
[super viewDidLoad];
a=0;
b=0;
c=0;
d=0;
storeVariables = [[NSMutableArray alloc] init];
}
-(IBAction)pauseButton:(id)sender{
a=3;
b=4;
c=5;
d=6;
[storeVariables addObject:[NSNumber numberWithInt:a]];
[storeVariables addObject:[NSNumber numberWithInt:b]];
[storeVariables addObject:[NSNumber numberWithInt:c]];
[storeVariables addObject:[NSNumber numberWithInt:d]];
NSLog(#"%d, %d, %d, %d", storeVariables[0], storeVariables[1], storeVariables[2], storeVariables[3]);
}
-(IBAction)resumeButton:(id)sender{
a = [storeVariables[0]];
b = [storeVariables[1]]
c = [storeVariables[2]]
d = [storeVariables[3]]
NSLog(#"%d, %d, %d, %d", a, b, c, d);
storeVariables = [[NSMutableArray alloc] init];
}

An IBAction is code. It can't store anything. You need to save your state somewhere like an instance variable of the object that implements the IBAction

This is what worked:
.h file-
#interface ViewController2 : UIViewController{
NSMutableArray *savedScoreData;
int PlayTimer;
int timeMinute;
int bonusPts;
int enemykill;
}
.m file-
- (void)viewDidLoad {
PlayTimer = 0;
timeMinute = 0;
bonusPts = 0;
timeMinute = 0;
savedScoreData = [[NSMutableArray alloc] init];
}
- (IBAction)pauseButton:(id)sender {
NSLog(#"pause-before: %d, %d, %d,",PlayTimer,enemykill,bonusPts);
[GameTimer invalidate]; //this constantly changes the PlayTimer & timeMinute variables
[characterTimer invalidate];
[enemyTimer invalidate]; //this constantly changes the enemyKill & bonusPts variables
[_bonusImgHolder removeFromSuperview];
if([_soundEnable isEqualToString:#"YES"]){
[_player2 pause];
}
//NSLog(#"%tu",_player2.playing);
_resumeButton.hidden = NO;
_pauseButton.hidden = YES;
NSLog(#"pause-after: %d, %d, %d,",PlayTimer,enemykill,bonusPts);
//[sender num :PlayTimer];
[savedScoreData addObject:[NSNumber numberWithInteger: PlayTimer]];
[savedScoreData addObject:[NSNumber numberWithInteger: timeMinute]];
[savedScoreData addObject:[NSNumber numberWithInteger: enemykill]];
[savedScoreData addObject:[NSNumber numberWithInteger: bonusPts]];
NSLog(#"%i", [savedScoreData[0] intValue]);
NSLog(#"%d", [savedScoreData[1] intValue]);
NSLog(#"%d", [savedScoreData[2] intValue]);
NSLog(#"%d", [savedScoreData[3] intValue]);
}
- (IBAction)resumeButton:(int)pauseButton{
NSLog(#"resume-before: %d, %d, %d,",PlayTimer,enemykill,bonusPts);
PlayTimer = [savedScoreData[0] intValue];
timeMinute = [savedScoreData[1] intValue];
enemykill = [savedScoreData[2] intValue];
bonusPts = [savedScoreData[3] intValue];
NSLog(#"%d", (int)enemykill);
_resumeButton.hidden = YES;
_pauseButton.hidden = NO;
if([_soundEnable isEqualToString:#"YES"]){
[_player2 play];
}
GameTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(CollectPoints) userInfo:nil repeats:YES];
characterTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(Jumping) userInfo:nil repeats:YES];
enemyTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(enemyTravel) userInfo:nil repeats:YES];
NSLog(#"resume-after: %d, %d, %d,",PlayTimer,enemykill,bonusPts);
[savedScoreData removeAllObjects];
}

Related

Start and Stop functionality of StopWatch is not coordinated iOS

I am creating a stopwatch and the start and stop functionality is not coordinated. When the timer stops, it doesn't start where it left of.
The code looks like this:
self.endDate = [NSDate dateWithTimeIntervalSinceNow:12.0f*60.0f];
-(void)startPressed:(id)sender{
if(!_running){
_running = TRUE;
[sender setTitle:#"Stop" forState:UIControlStateNormal];
if (_stopTimer == nil) {
_stopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(changeTimer:)
userInfo:nil
repeats:YES];
}
}else{
_running = FALSE;
[sender setTitle:#"Start" forState:UIControlStateNormal];
[_stopTimer invalidate];
_stopTimer = nil;
}
}
- (void)changeTimer:(NSTimer*)timer {
_timeInterval = [self.endDate timeIntervalSinceNow];
self.timerControl1.minutesOrSeconds = ((NSInteger)_timeInterval)%60;
self.timerControl2.minutesOrSeconds = (NSInteger)(_timeInterval/60.0f);
self.timerControl3.minutesOrSeconds = ((NSInteger)_timeInterval)%60;
}
I know it is because of timeIntervalSinceNow. But, how to change this? Need some guidance on this.
The problem:
When you stop the stopwatch and start it again after 3s for example, it shld still start back from the same timing. but both my code, the start and stop timing are different, they are starting from a different timing. Need help to solve this.
don't use the endDate in changeTimer but use the endDate only to init the timer
#import "RimsViewController.h"
#interface RimsViewController ()
#property(weak) IBOutlet UILabel *label;
#property(strong) NSDate *endDate;
#end
#implementation RimsViewController {
BOOL _running;
NSTimeInterval _timeInterval;
NSTimer *_stopTimer;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.endDate = [NSDate dateWithTimeIntervalSinceNow:10*60];
_timeInterval = [self.endDate timeIntervalSinceNow];
}
-(IBAction)startPressed:(id)sender{
if(!_running){
_running = TRUE;
[sender setTitle:#"Stop" forState:UIControlStateNormal];
if (_stopTimer == nil) {
_stopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(changeTimer:)
userInfo:nil
repeats:YES];
}
}else{
_running = FALSE;
[sender setTitle:#"Start" forState:UIControlStateNormal];
[_stopTimer invalidate];
_stopTimer = nil;
}
}
- (void)changeTimer:(NSTimer*)timer {
_timeInterval -= 1;// [self.endDate timeIntervalSinceNow];
NSUInteger secs = _timeInterval;
int h = (NSUInteger)secs/3600;
secs-=h*3600;
int m = (NSUInteger)secs/60;
secs-=m*60;
int s = secs;
self.label.text = [NSString stringWithFormat:#"%d / %d / %d", h, m, s];
}
#end

NSTimer Countdown issue

Hello I recently added a timer in my app so when the user clicks the balloon it starts the timer but I also have a tap counter hooked to the button as well. So heres my issue when I press the balloon multiple times the tap counter works and so does the timer but when start to tap faster the timer becomes stuck in a loop and when I stop tapping it, it counts down past zero into negatives really fast
How do I fix this?
- (IBAction)yourbuttonClicked1:(UIButton *)sender
{
//start a background sound
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"tap" ofType:
#"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath ];
myAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil ];
[myAudioPlayer play];
//for Switch view
ViewController2 *nextView = [[ViewController2 alloc] initWithNibName:#"ViewController"
bundle: nil];
[self.navigationController pushViewController:nextView animated:YES];
This is where the timer code is I think it might be conflicting with the tap counter?
myTime = 60;
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(countDown) userInfo:nil repeats:YES];
}
-(void)countDown {
myTime = myTime;
countdownLabel.text = [NSString stringWithFormat:#"%i", myTime];
if (myTime == 0) {
[countdownTimer invalidate];
}
}
This is where the timer code ends!
- (void) saveNumberOfTaps:(int)numberOfTaps {
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:numberOfTaps]
forKey:#"numberOfTaps"];
NSLog(#"Saved numberOfTaps: %i", numberOfTaps);
}
- (int) getNumberOfTaps {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"numberOfTaps"] intValue]) {
int numberOfTaps = [[[NSUserDefaults standardUserDefaults]
objectForKey:#"numberOfTaps"] intValue];
NSLog(#"Getting numberOfTaps: %i", numberOfTaps);
return numberOfTaps;
}
else {
NSLog(#"No taps saved yet");
return 0;
}
}
Try to modify your timer initialization in such way:
myTime = 60;
[countdownTimer invalidate];
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(countDown) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:countdownTimer forMode:NSRunLoopCommonModes];
Check your -countDown method:
myTime = myTime;
Is it typo?

NSMutableArray returns empty

I am writing a simple program that, I display a number from array 1 on a label and then move the number to array 2. However, the array keeps returning empty.
Here's my code.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self firstArrayInit];
[self secondArrayInit];
[self tranferA1toA2];
}
-(NSMutableArray *) firstArrayInit{
self.originalArray = [NSMutableArray array];
for (int i=0; i<16; i++) {
[self.originalArray addObject:[NSNumber numberWithInteger:i]];
}
return self.originalArray;
}
-(NSMutableArray *)secondArrayInit{
self.secondArray = [NSMutableArray array];
return self.secondArray;
}
-(void) tranferA1toA2{
self.mytimer = [NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:#selector(displayNumber)
userInfo:nil
repeats:YES];
}
-(NSMutableArray *)addToSecondArray:(int)myNumber{
[self.secondArray addObject:[self.originalArray objectAtIndex:myNumber]];
return self.secondArray;
}
-(void) displayNumber{
static int num=0;
if (num < level){
myLabel.text = [NSString stringWithFormat:#"%#", [self.originalArray objectAtIndex:num]];
[self addToSecondArray:num];
}
else{
[self.mytimer invalidate];
[myLabel setText:#""];
}
num++;
}
I've tried printing out the values in array 2 from displayNumber and it works. But, outside the function the array is empty.
Your code works as it is supposed to. The problem is that you check the array too early, even before the timer is fired for the first time. Check the array after the timer is invalidated

How to hide Text from UILabel in IOS

I'm trying to display a set of numbers on a UILabel sequentially.
For example: I have an array with 5 numbers and each time I want one number from the array to be displayed for 2 seconds on the screen then disappear and then the next number…
This is what i have done so far, but it is not quite what I want. The code below just displays the last number in the array for 2 seconds and then disappears.
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray* myArray = [NSMutableArray array];
for (int i=0; i<5; i++) {
NSNumber *temp;
temp = [myArray objectAtIndex:i];
[self displayNumber:temp];
[myLabel setHidden:NO];
}
}
-(void) displayNumber: (NSNumber *) myNumber{
myLabel.text = [NSString stringWithFormat:#"%#", myNumber];
NSTimer *myTimer;
myTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(hideLabel) userInfo:Nil repeats:NO];
}
-(void) hideLabel{
[myLabel setHidden:YES];
}
I thought about having 5 functions and each gets called sequentially after 2 seconds, but that is very inefficient.
Are there any other ways I can do this?
Change this method
Hope it will works for you what you want
1) Define
NSMutableArray* myArray , int repeatCount; and NSTimer *myTimer in .h file and set its property;
2)
-(void)viewDidLoad
{
[super viewDidLoad];
//This will initialize your timer
myTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(showLabel) userInfo:Nil repeats:NO];
//This will trigger your timer
[myTimer fire];
//Your timer will run in a loop
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
myArray = [NSMutableArray array];
}
-(void) displayNumber: (NSNumber *) myNumber{
myLabel.text = [NSString stringWithFormat:#"%#", myNumber];
}
-(void) showLabel{
if(repeatCount >= [myArray count])
{
repeatCount = 0;
}
NSNumber *temp = [myArray objectAtIndex:repeatCount];
repeatCount ++;
[self displayNumber:temp];
[myLabel setHidden:NO];
}
I think, that you can use timer with counter.
Create 3 properties:
#property (nonatomic, assign) int counter;
#property (nonatomic, strong) NSArray *array;
#property (nonatomic, strong) NSTimer *timer;
Set them in viewDidLoad: and start timer(with repetition):
- (void)viewDidLoad {
[super viewDidLoad];
_counter = 0;
_array = #[#0, #1, #2, #3, #4, #5];
_timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(nextLabel) userInfo:Nil repeats:YES];
}
Update label:
- (void)nextLabel{
if (_counter == [_array count]) {
//stop in the end of array
[_timer invalidate];
return;
}
[_label setText:[NSString stringWithFormat:#"%#", _array[_counter]]];
_counter++;
}
Pass the array with NSNumber instances to the below method
- (void)updateLabelWithArray:(NSMutableArray *)array
{
if ([array count] != 0)
{
myLabel.text = [NSString stringWithFormat:#"%#", [array firstObject]];
[array removeObjectAtIndex:0];
[self performSelector:#selector(updateLabelWithArray:)
withObject:array
afterDelay:2.0f];
}
}
This should do.
Try this:
// Initialize the timer when you want to change the first number
[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(changeNumber:) userInfo:#{#"currentNumber" : [NSNumber numberWithInt:0]} repeats:NO];
-(void)changeNumber:(NSTimer *)timer
{
NSDictionary * dictionary = [timer userInfo];
int number = [(NSNumber *)[dictionary objectForKey:#"currentNumber"] integerValue];
if (number < [numbersArray count])
{
myLabel.text = [NSString stringWithFormat:#"%#", [numbersArray objectAtIndex:number]];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(changeNumber:) userInfo:#{#"currentNumber" : [NSNumber numberWithInt:number + 1]} repeats:NO];
}
}
try this hope this helps u .. :)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[super viewDidLoad];
myArray = [[NSMutableArray alloc]initWithObjects:[NSNumber numberWithInt:3],[NSNumber numberWithInt:5],[NSNumber numberWithInt:6],[NSNumber numberWithInt:7],[NSNumber numberWithInt:10], nil]; //your array contains any number you want
index = 0; //showing the numbers from 0th index to last indx
[self.myLabel setHidden:NO];
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(DisplayFortwoSec) userInfo:nil repeats:YES];//call the method reguraly for 2 sec
}
- (void)DisplayFortwoSec
{
[self.myLabel setHidden:YES];
if(index == ([myArray count] - 1))
index = 0;//other stuffs to come out of loop like invalidating the timer
[self.myLabel setHidden:NO];
NSNumber *num = [myArray objectAtIndex:index];
NSString *strNum = [num stringValue];
self.myLabel.text = strNum;
[self.myLabel setHidden:NO];
index ++;
}

How to get a function to pause until the NSTimer selector is finished?

I have an NSTimer in another function but I want to be able to wait for the NSTimer to become invalidated before continuing on with the code is there a way to do this?
- (IBAction)addLifePoints:(UIButton *)sender
{
[[ARCHDuelCalculator sharedARCHDuelCalculator] setLifePointDelta:[NSNumber numberWithInt: [self.hiddenTextField.text intValue]]];
[[ARCHDuelCalculator sharedARCHDuelCalculator] setAddOrSubstract: YES];
[[ARCHDuelCalculator sharedARCHDuelCalculator] applyingDeltaToLifePointsByDelta];
// This will animate the life points
animationTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(animateLifePoints) userInfo:nil repeats:YES];
// This is where we bring it back to the view controller
self.duelistOneLifePoints.text = [[ARCHDuelCalculator sharedARCHDuelCalculator].duelistOneLifePoints stringValue];
self.duelistTwoLifePoints.text = [[ARCHDuelCalculator sharedARCHDuelCalculator].duelistTwoLifePoints stringValue];
self.hiddenTextField.text = #"";
[self syncTextField: self.hiddenTextField];
[self.hiddenTextField resignFirstResponder];
}
- (void) animateLifePoints
{
NSNumber *sections = [[ARCHDuelCalculator sharedARCHDuelCalculator] getLifePointSections];
for(int timer = 0; timer < 100; ++timer)
{
self.duelistOneLifePoints.text = [[[ARCHUtilities sharedARCHUtilities] subtractTwoNSNumbersByDataType:#"int" firstNumber:[NSNumber numberWithInt: [self.duelistOneLifePoints.text intValue]] secondNumber:sections] stringValue];
if ((timer % 14) == 0)
{
[self playLifePointSound:#"mainLifePointSound" typeOfFile:#"mp3"];
}
}
[animationTimer invalidate];
}
hope this works:
-split addLifePoints into 2 methods.
-put code after the nstimer in another method (newMethod)
-call newMethod right after the nstimer is invalidated.
- (IBAction)addLifePoints:(UIButton *)sender
{
[[ARCHDuelCalculator sharedARCHDuelCalculator] setLifePointDelta:[NSNumber numberWithInt: [self.hiddenTextField.text intValue]]];
[[ARCHDuelCalculator sharedARCHDuelCalculator] setAddOrSubstract: YES];
[[ARCHDuelCalculator sharedARCHDuelCalculator] applyingDeltaToLifePointsByDelta];
// This will animate the life points
animationTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(animateLifePoints) userInfo:nil repeats:YES];
}
- (void) animateLifePoints
{
NSNumber *sections = [[ARCHDuelCalculator sharedARCHDuelCalculator] getLifePointSections];
for(int timer = 0; timer < 100; ++timer)
{
self.duelistOneLifePoints.text = [[[ARCHUtilities sharedARCHUtilities] subtractTwoNSNumbersByDataType:#"int" firstNumber:[NSNumber numberWithInt: [self.duelistOneLifePoints.text intValue]] secondNumber:sections] stringValue];
if ((timer % 14) == 0)
{
[self playLifePointSound:#"mainLifePointSound" typeOfFile:#"mp3"];
}
}
[animationTimer invalidate];
[self newMethod]; //////////////////// ADD THIS LINE ALSO, continue code
}
-(void)newMethod{
//...so continue code...
// This is where we bring it back to the view controller
self.duelistOneLifePoints.text = [[ARCHDuelCalculator sharedARCHDuelCalculator].duelistOneLifePoints stringValue];
self.duelistTwoLifePoints.text = [[ARCHDuelCalculator sharedARCHDuelCalculator].duelistTwoLifePoints stringValue];
self.hiddenTextField.text = #"";
[self syncTextField: self.hiddenTextField];
[self.hiddenTextField resignFirstResponder];
}

Resources