UILabel only displaying odd objects in NSArray - iphone

I have an int which defines the objectAtIndex, which gives it to the string, which then displays it in the UILabel, HOWEVER, when I modify the array (add a word to it in this case) when I have the UILabel go through the array it only displays the odd ones. I have done an NSLog and found out that it DOES PASS EVERY SINGLE THING to the string, but the Label isn't displaying every single one, it only does it the first time, then I modify the array, and it only does odd
edit: the code:
- (void) stuff {
NSArray *indivwords = [sentence componentsSeparatedByString:#" "];
count = [indivwords count]; //count=int
if (i < count) {
NSString *chunk = [indivwords objectAtIndex:i];
[word setText:chunk];
NSLog(chunk);
i++;
} else {
word.textColor = [UIColor greenColor];
[word setText:#"DONE"];
}
}
All of this is being controlled by an NSTimer, which sets it off based on a slider value. Also i is set to 0 in the IBAction
The IBAction code:
word.textColor = [UIColor whiteColor];
[timer invalidate];
i = 0;
speedd = (1/speed.value)*60;
timer = [NSTimer scheduledTimerWithTimeInterval:(speedd) target:self selector:#selector(stuff) userInfo:nil repeats:YES];
EDIT:
I fixed it! What I did was call this after i reached the count
-(void)stoptimer
{
[timer invalidate];
timer = [NSTimer scheduledTimerWithTimeInterval:(.01) target:self selector:#selector(empty) userInfo:nil repeats:YES];
}
empty is just a void with nothing in it, well, all I did was add a comment,
//don't look over here, nothing to see here, oh look at that
Somebody can close this if they want

You said the time interval of your NSTimer is controlled by a slider. Perhaps you are starting a new timer instance every time you change the slider value, so after a change you would have two timers running. The first one updates the label and increments i. The second one comes right after the first and finds i's value incremented, so it displays the next chunk instead of the current one.
Count the instances of your timer - NSLog the timer in the timer callback and compare the results - it may be that you're firing more than one.

My guess is that you have two different actions calling this method, when you think there should be one. I'd put a break point in there, and see if it stops where you think it should.

Related

Scroll UISlider Automatically

So currently I have a UISlider in a UIViewcontroller that is meant to start animations within subviews when the user slides.. Basically when the user slides I have this battery with a filling in it that fills the empty battery image with a bar to indicate power within a cell, and the user can slide to see the energy the battery has at certain times of the day.
At the moment, when the View loads I would like the UISlider to AUTOMATICALLY start sliding from the beginning of the slider and scroll to the end within, lets say 5 seconds.
I implemented a loop that cycles through all the values of the uislider using this loop
for (int i = 0; i < [anObject count] - 2; i++)
{
sleep(.25);
NSUInteger index = (NSUInteger)(slider.value + 0.5); // Round the number.
[slider setValue:index animated:YES];
}
[anObject count] - 2 is equal to 62 at this time of day but will change and increment every 15 seconds because I'm fetching data from a server.
But that aside, why doesn't this work? The loop?
EDIT:
So heres what I did with NSTIMER
[NSTimer timerWithTimeInterval:0.25 target:self selector:#selector(animateSlider) userInfo:nil repeats:NO];
and animateSlider looks like this:
- (void)animateSlider:(NSTimer *)timer
{
NSLog(#"Animating");
NSUInteger index = (NSUInteger)(slider.value + 0.5); // Round the number.
[slider setValue:index animated:YES];
}
But no luck... Why isn't NSTimer "firing"..... I remmeber vaguely there was a method that FIRES an nstimer method but not sure if that's needed...
EDIT:
Ahh it does need "Fire"....
NSTimer *timer = [NSTimer timerWithTimeInterval:0.25 target:self selector:#selector(animateSlider) userInfo:nil repeats:NO];
[timer fire];
But for some reason it only fires once.... Any ideas ?
"for some reason it only fires once..."
If you changed the NSTimer set up to this:
NSTimer *timer =
[NSTimer scheduledTimerWithTimeInterval:0.25
target:self
selector:#selector(animateSlider:)
userInfo:nil
repeats:YES];
This would schedule the timer on the current run loop immediately.
And since the "repeats" parameter is "YES", you'd then repeat the timer every quarter second, until you invalidate the timer (which you should do when the ending condition is reached, like when the slider reaches its destination).
P.S. You'd need to change the selector method declaration of your timer's target slightly. According to Apple's documentation, "The selector must correspond to a method that returns void and takes a single argument. The timer passes itself as the argument to this method."
So declare "animateSlider" like this instead:
- (void)animateSlider: (NSTimer *) theTimer;

read nsmutablearray at different time intervals

I have this NSMutable array. Reading it one by one after every two seconds and updating textview. But now i want is to read from NSMutable array one by one at different timeintervals than every two seconds. How i can do that.
- (void)viewDidLoad{
myArray = [[NSMutableArray alloc]initWithObjects:#"String1",#"String2",#"String3",#"String4", #"String5",..... nil];
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(updateText:)
userInfo:nil
repeats:YES];
- (void)updateText:(NSTimer *)theTimer
{
if (index < [myArray count])
{
myTextView.text = [myArray objectAtIndex:index];
index++;
}
else
index = 0;
}
}
Thanks for help.
If all you need is to change the interval value every time the view loads you can try with a random number, in the next example it'll return a random number between 2 and 10:
[NSTimer scheduledTimerWithTimeInterval:arc4random() % 10 + 2
target:self
selector:#selector(updateText:)
userInfo:nil
repeats:YES];
Simple: cancel the timer each time and recreate it with the desired interval (hang onto a reference to the timer of course).
in your updateText selector just create a new NSTimer with different intervals until there are no more objects in the array.
Use performSelector:withObject:afterDelay, but using a random delay!
[self performSelector:#selector(updateText:) withObject:nil afterDelay:arc4random()%10+2];

Boost-button delay

I am making a game with a boost button. Of course, just leaving it as enabled would allow the player to tap it constantly. So, I need a 20 second delay before it is possible to push the button again. Also, would it be possible to show this progression on the button, preferably on the button itself?
In the future please try to show what you have tried to solve your problem. However, since you are new I'm going to let it slide once!
This code uses a NSTimer that is called once per second. It will fire what ever code you specify for "Boost". It will also disable user interaction on your button until it has been 20 seconds from when the button was pressed at which point it will allow the user to press the button again, and finally, this code displays how many seconds remain until "Boost" can be used again on the titleLabel property of your button.
- (IBAction)buttonPressed:(id)sender
{
myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(activateBoost) userInfo:nil repeats:YES];
}
- (void)activateBoost
{
if (myButton.userInteractionEnabled == YES) {
//Put your Boost code here!
}
if ([myButton.titleLabel.text intValue] == 0) {
[myTimer invalidate];
[myButton setTitle:#"20" forState:UIControlStateNormal];
myButton.userInteractionEnabled = YES;
}else{
myButton.userInteractionEnabled = NO;
int currentTime = [myButton.titleLabel.text intValue];
int newTime = currentTime - 1;
myButton.titleLabel.text = [NSString stringWithFormat:#"%d",newTime];
}
}
In order for the above code to work, you will need the declare a NSTimer named "myTimer" and a UIButton "myButton". You will also need to set the buttons initial text to "20".

objective-c: Animate button before timer ends

I'm working on a very simple iPhone game that involves choosing the right colored button as many times in a row based on a randomized voice prompt. I have it set up so that if the button is one color and gets clicked, it always goes to a hard-coded color every time (e.g. if you click red, it always turns blue). The color change method is set up in an IBOutlet. I have a timer set up in a while loop, and when the timer ends it checks if the player made the right selection. The problem is that the button color change does not occur until after the timer runs out, and this causes a problem with the method used to check the correct answer. Is there a way to make this color change happen instantly? From what I've searched I know it has something to do with storyboard actions not occurring until after code executes, but I haven't found anything with using a timer. Here is a section of the method that calls the timer if the answer is correct:
BOOL rightChoice = true;
int colorNum;
NSDate *startTime;
NSTimeInterval elapsed;
colorNum = [self randomizeNum:middle];
[self setTextLabel:colorNum];
while (rightChoice){
elapsed = 0.0;
startTime = [NSDate date];
while (elapsed < 2.0){
elapsed = [startTime timeIntervalSinceNow] * -1.0;
NSLog(#"elapsed time%f", elapsed);
}
rightChoice = [self correctChoice:middleStatus :colorNum];
colorNum = [self randomizeNum:middle];
}
One of two things stood out
You're using a while loop as a timer, don't do this - the operation is synchronous.
If this is run on the main thread, and you code doesn't return, your UI will update. The mantra goes: 'when you're not returning you're blocking.'
Cocoa has NSTimer which runs asynchronously - it is ideal here.
So let's get to grips with NSTimer (alternatively you can use GCD and save a queue to an ivar, but NSTimer seems the right way to go).
Make an ivar called timer_:
// Top of the .m file or in the .h
#interface ViewController () {
NSTimer *timer_;
}
#end
Make some start and stop functions. How you call these is up to you.
- (void)startTimer {
// If there's an existing timer, let's cancel it
if (timer_)
[timer_ invalidate];
// Start the timer
timer_ = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(onTimerFinish:)
userInfo:nil
repeats:NO];
}
- (void)onTimerFinish:(id)sender {
NSLog(#"Timer finished!");
// Clean up the timer
[timer_ invalidate];
timer_ = nil;
}
- (void)stopTimer {
if (!timer_)
return;
// Clean up the timer
[timer_ invalidate];
timer_ = nil;
}
And now
Put your timer test code in the onTimerFinish function.
Make an ivar that stores the current choice. Update this ivar when a choice is made and make the relevant changes to the UI. Call stopTimer if the stop condition is met.
In the onTimerFinished you can conditionally call and startTimer again if you desire.
Hope this helps!

Approaching the label at timer, it can's renewal string of label

I make a Voca App.
After playing voice file and showing English text, it shows the meaning label.
So, I want to hide label texts before playing next voice file.
I have problem.df
These labels are not hidden.
Approaching the label at timer, it can's renewal string of label.
What is the problem?
Help me, please!
- (void)showLabel{
Word *word = [wordArray objectAtIndex:selectedIndex];
[simpleMeaning setText:word.mean];
NSTimer *timer2 = [[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(hideLabel) userInfo:nil repeats:NO] retain];
[timerArray addObject:timer2];
[timer2 release];
timer2 = nil;
}
- (void)hideLabel{
[simpleMeanig setText:#" "];
++selectedIndex;
[self filePlay];
}
I'm wondering if the call to filePlay is blocking the UI update (hard to tell without seeing the guts of filePlay).
This is just a guess, but instead of:
[self filePlay];
try:
[self performSelectorOnMainThread:(#selector(filePlay) withObject:nil waitUntilDone:NO];
This will defer the call to filePlay until after the current event (as a result of the timer firing) has been processed (which should in turn should allow the UI to refresh itself).