Repeatedly changing UIImageView image freezes - ios

I create six (6) UIImageView's and add them to the view. I then create a timer running at 0.01 second intervals and incrementing the number by a set amount. Every so often the numbers just stop changing. Below is a sample of the code I'm running to better show what I'm doing.
NSTimer *newTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(numberTimerFired:) userInfo:nil repeats:YES]];
[newTimer fire];
// Assume that I've created six (6) UIImageView's and stored them in an array called digitImageViewArray (the right most UIImageView would be index 5)
- (void)numberTimerFired:(NSTimer *)newTimer
{
// self.currentNumber is the NSInteger property that is incremented each repetition
int tempScore = self.currentNumber;
int currentDigit = 5;
do {
int digit = tempScore % 10;
tempScore /= 10;
[[self.digitImageViewArray objectAtIndex:currentDigit] setImage:[self.numberImageArray objectAtIndex:digit]];
currentDigit--;
} while (tempScore !=0);
self.currentNumber += 133; // 133 can be any number to increment by
}
I have other conditions setup to stop the timer when the number reaches the final number. As I said, as this number goes up, whether the final number is 999,999 or 50,000 it just freezes intermittently as it rises. Any help would be greatly appreciated!
I also checked the Profile and watch CPU / memory usage. It's not even breaking 35% CPU and the memory usage is very insignificant. I've tried several fixes, such as adjusting the time interval the NSTimer runs at. However, if I leave the screen after it runs and come backā€¦ it runs smoothly with no glitching.

Related

How to increase index within a loop & stop enumerating?

I've ran into a situation where I need a loop, but the code below returns only the very last index value. I need it to return the next value and stop enumerating. To explain better, say I have numbers 0-10, when pressing a button I need the index to increase by one. Now say I keep pressing this button until the index reaches 10, on the next press, the index needs to be back at zero (aka cycle through.)
Any help would be appreciated & I will most definitely accept the best answer.
Thanks in advance!
//grabs current index in a scrollview
long long currentSelectedIndex = [preview.swipeView currentIndex];
long long totalNumberOfAvailableSlots = [preview.swipeView indexTotal]; //index total is never an absolute value
#autoreleasepool {
//currentSelectedIndex is supposed/always to be zero on first run
for (int i; = (int)currentSelectedIndex; i <= totalNumberOfAvailableSlots; i++){
NSLog(#"loop: %d", i);
if (i == totalNumberOfAvailableSlots){
i = -1;
[preview.swipeView scrollToIndex:i]; //this will cause [preview.swipeView currentIndex] to be updated with "i" value.
}
}
}
As per my comment, the behaviour you seem to be after is to automatically swipe through the contents of swipeView.
Make a timer which calls the swipeToNext method:
myTimer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:#selector(swipeToNext) userInfo:nil repeats:YES];
Then handle the swipe:
- (void)swipeToNext {
if ([preview.swipeView currentIndex] < [preview.swipeView indexTotal]) {
//Can swipe forward
[preview.swipeView scrollToIndex:[preview.swipeView currentIndex]+1];
} else {
//At last index. Need to go to first.
[preview.swipeView scrollToIndex:0];
}
}
sounds like you need currentSelectedIndex to go through this repeating sequence 0, 1, 2, 3, 4,5, 6, 7, 8, 9, 10, 0, 1, ...
within formLoad you need to initialise your counter
currentSelectedIndex = 0
within the button pressed method, increment the counter - but using the modulo operator to return the remainder - in this case of dividing by 11
currentSelectedIndex = (currentSelectedIndex + 1) % 11
in general, you can make a sequence of 0...n like this
currentSelectedIndex = (currentSelectedIndex + 1) % (n + 1)

can I make glsl bail out of a loop when it's been running too long?

I'm doing some glsl fractals, and I'd like to make the calculations bail if they're taking too long to keep the frame rate up (without having to figure out what's good for each existing device and any future ones).
It would be nice if there were a timer I could check every 10 iterations or something....
Failing that, it seems the best approach might be to track how long it took to render the previous frame (or previous N frames) and change the "iterate to" number dynamically as a uniform...?
Or some other suggestion? :)
As it appears there's no good way to do this in the GPU, one can do a simple approach to "tune" the "bail after this number of iterations" threshold outside the loop, once per frame.
CFTimeInterval previousTimestamp = CFAbsoluteTimeGetCurrent();
// gl calls here
CFTimeInterval frameDuration = CFAbsoluteTimeGetCurrent() - previousTimestamp;
float msecs = frameDuration * 1000.0;
if (msecs < 0.2) {
_dwell = MIN(_dwell + 16., 256.);
} else if (msecs > 0.4) {
_dwell = MAX(_dwell - 4., 32.);
}
So my "dwell" is kept between 32 and 256, and more optimistically raised than decreased, and is pushed as a uniform in the "gl calls here" section.

Game: ScoreNumber does not increase by 1. It increases by 4 every time (sometimes, 10)

I have a game where you bounce on platforms. I want the score to increase by 1 every time you bounce on a platform. However, it keeps increasing by some random number every time (like 10).
In Game.h I have:
int ScoreNumber;
IBOutlet UILabel *ScoreLabel;
-(void)Score;
...
In Game.m I have:
-(void)Score {
ScoreNumber = ScoreNumber +1.0;
ScoreLabel.text = [NSString stringWithFormat:#"%i", ScoreNumber];
}
-(void)PlatformMoving {
if (CGRectIntersectsRect(Bird.frame, Platform1.frame)) {
[self Score];
}
}
...
This should count by 1 every time but it counts by more than 1
If you place a breakpoint in your (void)Score method you'll probably see that its being called multiple times per bounce because the rectangles probably overlap for multiple frames. You could place a check inside the (void)PlatformMoving method to see if the last test failed before calling Score again. This would ensure that Score is never called on 2 consecutive frames and should prevent scoring any more than one point per bounce.

Xcode int variable holding multiple values?

In my "xcode" timer project, I have a int variable named "overall". When I first set up my timer the overall variable is set to the amount of seconds wanted for the timer. I then have an NSTimer taking a second of the variable every second.
overall = (timerMin * 60) + (timerHour * 60 * 60) + timer;
[self setTimer];
When i first set the variable
If the app enters the background I record the date and then the date of when it enters the foreground. I then find out the difference of the two dates and take it away from the overall variable. And recall the NSTimer.
[Countdown invalidate];
Countdown = nil;
overallBackground = [saveOverall integerForKey:overall_save];
int newOverall = (int)overallBackground - secondsInBackground;
overall = newOverall;
[self setTimer];
When i set it after re-entering the app from background
The problem I have is that even though I have been into the background and reset the overall variable when the Timer was restarted the overall variable number from before was still there but the variable was also storing the new number!
2014-05-11 16:48:18.759 Timer[836:60b] overall:3595 - Old number
2014-05-11 16:48:19.044 Timer[836:60b] overall:3591 - New number
2014-05-11 16:48:19.759 Timer[836:60b] overall:3594 - Old number
2014-05-11 16:48:20.044 Timer[836:60b] overall:3590 - New number
NSLog(#"overall:%d", overall);
overall = overall - 1;
[saveOverall setInteger:overall forKey:overall_save];
[saveOverall synchronize];
hours = overall / 3600;
minutes = overall - (hours * 3600);
minCon = minutes / 60;
seconds = minutes - (minCon * 60);
From the log above you can see what I mean. I am printing the exact same variable to the log, just so you know.
My question is why is this happening? And how do I stop it?

Adding a visual side to a schedule in Cocos2d

I am trying to make a timer for my game that counts down from a number, let's call it 100. I am following the cocos2d best practices, and therefore I am not using a NSTimer. What I am looking to do is that every second, I want to numbers of this timer to change. I could probably find a way to do it using a spritesheet with all of the numbers from 100-0, but I know there is a way to do it using just the numbers 0-9 and their pictures.
This is the code that I am using, with the corresponding -(void)
[self schedule: #selector(tick:)];
[self schedule: #selector(tick2:) interval:1];
All in all, I would like to know how to make it count down from 100, but also to know how to make those ticks decrease the value by 1 every second.
Initialize an integer variable that will keep your countdown value:
int count = 100;
You will want to keep a label (CCLabelBMFont etc) to display this count value. I recommend Glyph Designer (or Hierro if you want something free) to generate the 0 to 9 cocos2D-compatible font bitmaps, which you can then use in your CCLabelBMFont:
CCLabelBMFont* countLabel = [CCLabelBMFont labelWithString:#"0" fntFile:#"myFont.fnt"];
Next, schedule a single tick function that will fire every second:
[self schedule: #selector(tick:) interval:1];
This tick function decrements count by 1 each time it is called. Also, add the condition that if count has reached 0, it will unschedule itself:
-void tick:(ccTime) dt
{
count --; // decrement count by 1 each time this function is called
if (count == 0)
[self unschedule: #selector(tick:)];
}
And finally, in your main update loop (or even in the tick function itself after you decrement your count), you can update and redraw this label with the latest value each time:
[countLabel setString:[NSString stringWithFormat:#"%i", count]];
All the best.

Resources