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)
Related
In my app, I have created a circular, continuous slidable CircularSlider (this one). It has a minimumValue of 1.0 and a maximumValue of 10. Now, I'd like my users to be able to just keep sliding in circles to increase an NSInteger used somewhere in the app.
I tried doing that by writing the code below.
- (void)sliderChanged:(UICircularSlider *)slider {
int val = (int)slider.value;
slider.value = val;
int delta = val - self.oldValue;
if (self.oldValue == self.circularSlider.maximumValue && val == 0) {
delta = 1;
}
self.number += delta;
self.oldValue = val;
}
This works, but really sketch. Sometimes the value will drop by 10, caused by the slider giving me value of 10 and right afterwards a value of 0. It also doesn't work if the users starts scrubbing backwards and numbers start decreasing. I was wondering if there's a better way to achieve the same thing. Any ideas?
I think a better approach is to first figure out what direction the user moved. This can be done by checking which direction has the closest distance between the new and the old position. Care must be taken to check for passing the border. Then it is a simple matter of adjusting the delta depending on direction.
My solution code assumes the the slider starts at zero, which I would recommend you to use instead of 1, since calculations are easier. If you really want to start at 1 it can be adjusted. I also have defined the maximum value as a constant SLIDER_MAX_VALUE, which you could change to a variable instead. Finally, I changed self.number to a CGFloat, so do the cast when using the number instead. This is important, otherwise you get rounding errors when sliding. If you really want an integer, use two variables, and assign the integer variable from the float.
#define SLIDER_MAX_VAL 10
- (void)sliderChanged:(UICircularSlider *)slider {
CGFloat delta = slider.value - self.oldValue;
if ((delta > 0 && delta < SLIDER_MAX_VAL / 2) ||
(delta < 0 && delta < -SLIDER_MAX_VAL / 2)) {
// Moving forward
if (delta < 0)
delta += SLIDER_MAX_VAL;
} else {
// Moving backward
if (delta > 0)
delta -= SLIDER_MAX_VAL;
}
self.number += delta; // Change to CGFloat
self.oldValue = slider.value;
}
I want to do something like this. I have a UISlider its minimum value shuld be 0 and the maximum value should be 1000.And I want to divide this range into 10 parts. Like this.
0-----100----200----300----400
When user drag the slider from 0 it should directly stop at 100 position without stopping inbetween 0 and 100 when he drag from 100 it should directly jump into 200 should not stop inbetween 100 and 200 likewise.How can I do this? please help me.
Thanks
You have to do this:
slider.maximumValue = numberOfSteps;
slider.minimumValue = 0;
slider.continuous = NO;
For setting
NSUInteger index = (NSUInteger)(slider_value + 0.5);
[slider setValue:index animated:NO];
Well, just assign your slider range 0...10 and multiply changed value by 100
I had the same need just like you the day before. With default UISlider, you can only increment either +1 or -1. Hence, if you are looking to have a increment in other values, you have to do it programmatically.
In your case, try this:
- (IBAction)[yourUISlider]:(id)sender {
[[yourUISliderProperty] setValue:((int)(( [yourUISlider].value + 50) / 100) * 100) animated:NO];
NSLog(#"%d", [yourUISlider].value );
}
It worked for me, try it out :)
And for other increment values, check out the formula here:
((int)(( [yourSlider] + [yourIncrement/2] ) / [yourIncrement]) *[yourIncrement])
Then NSLog or output the value.
I am making a reaction game, where you can destroy enemys and earn points. Now I would like to have combo points if you destroy them fast and if there is a specific time gap the combo multiplier should go to zero again.
I would like to multiple the points like this: 2 * 2 = 4 * 2 = 8 * 2 = 16 * 2...
(you get 2 points if you destroy an enemy).
I add the points here:
if (CGRectIntersectsRect(enemy.frame, player.frame)) {
points = points + 1;
[enemy removeFromParent];
}
I could always multiply the current points with 2, but I want to reset the combo multiplier if there is specific amount of time without getting points.
I hope someone can help me.
(code in objective c please)
It seems no more complicated than recording the time the last enemy was destroyed and then in the update: method deciding if the combo has elapsed as no more enemies were hit in whatever timeout period you allow.
I am not familiar with Sprite kit, but the update appears to pass the current time; excellent. You will need to record the following:
timeout (time): The current timeout. This will reduce as the game progresses, making it harder.
lastEnemyKillTime (time): the time the last enemy was killed.
comboPoints (integer): How many points the user gets per hit. This will increase as the combo extends.
points (integer): The current score.
So, something like this:
#interface MyClass ()
{
NSTimeInterval _timeout;
NSTimeInterval _lastEnemyKillTime;
BOOL _comboFactor;
NSUInteger _points;
}
#end
I guess Sprite Kit uses an init: method; use it to initialize the variables:
- (id)init
{
self = [super init];
if (self != nil) {
_timeout = 1.0;
_lastEnemyKillTime = 0.0;
_points = 0;
_comboPoints = 1;
}
}
The update: method would be something like:
- (void)update:(NSTimeInterval)currentTime
{
BOOL withinTimeout = currentTime - _lastEnemyKillTime <= _timeout;
if (CGRectIntersectsRect(enemy.frame, player.frame)) {
_inCombo = withinTimeout;
if (_inCombo)
_comboPoints *= 2;
_points += _comboPoint;
_lastEnemyKillTime = currentTime;
[enemy removeFromParent];
} else if (_comboPoints > 1 && !withinTimeout) {
_lastEnemyKillTime = 0.0;
_comboPoints = 1;
}
}
You need to keep track on the last enemy casual timestamp and the factor. When the next kill is processed, you check the timestamp, if it is below threshold, you raise the factor. The time of the current kill replaces the timestamp.
You could create a FightRecorder class as singleton, if you don't have a better place yet (services or sth).
NSDate *newKillTime = new NSDate;
FightRecorder recorder = [FightRecorder instance];
if([newKillTime timeIntervalSinceDate:recorder.lastKillTime] < SCORE_BOUNDS_IN_SEC) {
recorder.factor++; // could also be a method
points = points + [recorder calculateScore]; // do your score math here
}
else {
[recorder reset]; // set the inner state of the fight recorder to no-bonus
}
recorder.lastKillTime = newKillTime; // record the date for the next kill
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.
I need help with Action Script 2.0
I have this scoreboard system with 2 buttons one to count up to a certain number and the other to count down if i need to.
However, the problem with the count down button.
Count Down button code:
on(release) {
score.text = 0;
score.text = scorebk
_root.scorebk--;
if the score is 9 for example when i count down it adds up 1 and then it counts down normally, also when score is 0 it goes to -1...etc.
I do not want that. how can i stop this button from going to minus? and counts normally.
You just have to check that the value is greater than zero before you decrement:
on(release) {
if(scorebk > 0){
scorebk--;
}
score.text = scorebk;
}