I have an array of images. And I am trying to change the images randomly after 2 seconds.
-(void)loadImage
{
for(int i =0;i<=[imageArray count];i++)
{
imageView.image=[imageArray objecyAtIndex:i];
}
}
-(void)viewDidload
{
imageTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target:self selector:#selector(loadImage) userInfo:nil repeats: YES];
}
But it is not working for me . It will be great appreciable if any one help to do this. Thanks .
modify your code in following way ..
-(void)viewDidload
{
index = 0; //index should be instance variable
imageTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target:self selector:#selector(loadImage) userInfo:nil repeats: YES];
}
-(void)loadImage
{
if(index != imageArray.count-1)
{
imageView.image=[imageArray objecyAtIndex:index];
index++;
}
else
{
[imageTimer invalidate];
}
}
You have to make some changes in your loadImage method. You have to generate random number and set a range of the random numbers. I tried like this and it worked for me.
-(void)loadImage
{
NSString *max=#"3";
NSString *min=#"0";
int randNum = rand() % ([max intValue] - [min intValue]) + [min intValue];
_changeableImageView.image=[UIImage imageNamed:[imageArray objectAtIndex:randNum]];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_changeableImageView.image=[UIImage imageNamed:#"program.jpg"];
imageArray=[[NSMutableArray alloc]initWithObjects:#"corporate.jpg",#"district.jpg",#"program.jpg", nil];
imageTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target:self selector:#selector(loadImage) userInfo:nil repeats: YES];
}
I hope it will for for you.
-(void)loadImage
{
NSUInteger randomIndex = arc4random() % [imageArray count];
imageView.image = imageArray[randomIndex];
[self performSelector:#selector(loadImage) withObject:nil afterDelay:2.0];
}
-(void)viewDidload
{
[self performSelector:#selector(loadImage) withObject:nil afterDelay:2.0];
}
Your loadImage method does not select a random image from the array. What it actually does is iterate through every single member in the array and assign them to the image view one by one every time it is run.
To set a random image each time the method is called, your method should look like this:
-(void)loadImage
{
NSUInteger randomIndex = arc4random() % [imageArray count];
imageView.image = imageArray[randomIndex];
}
The problem with your code is that whenever the timer fires, the whole loop in loadImage is executed, so that your image is always the last image of the array.
You have to define a property that holds e.g. the index of the currently displayed image. In loadImage, you had to increment then this index (modulo the array size), and assign the next image to your imageView.
It's not working because every time loadImage is called you loop through and set every image in the array and therefore always end up with the last image in the array. Try something more like this:
-(void)loadImage{
int randNum = arc4random() % imageArray.count;
imageView.image=[imageArray objecyAtIndex:randNum-1];
}//end method
Related
Hi I'm using Xcode for an app and my scoring system goes up by 1 point every second. How do i make it start at 25 and then go up at 1 point per second. This is the code:
-(void)Scoring{
ScoreNumber = ScoreNumber + 1;
Score.text = [NSString stringWithFormat:#"Score: %i", ScoreNumber];
-(void)NewGame{
ScoreNumber = 0;
Score.text = [NSString stringWithFormat:#"Score: 0"];
Please help!!
In NewGame, you are setting ScoreNumber to 0. Set it to 25 instead:
-(void)NewGame{
ScoreNumber = 25;
Score.text = [NSString stringWithFormat:#"Score: 25"];
Try this:
- (void) newGameWithStartingScore:(int)startingScore {
// Set our label
Score.text = [NSString stringWithFormat:#"Score: %i", startingScore];
// Store our score in our dictionary
NSDictionary * userInfo = [#{#"currentScore" : #(startingScore)} mutableCopy];
// Start the timer
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(incrementScore:) userInfo:userInfo repeats:YES];
}
-(void)incrementScore:(NSTimer *)timer {
// Get current score
int currentScore = [timer.userInfo[#"currentScore"] intValue];
// Increment it
currentScore++;
// Update userInfo ref
timer.userInfo[#"currentScore"] = #(currentScore);
// Set our label
Score.text = [NSString stringWithFormat:#"Score: %i", currentScore];
// See if timer should continue
BOOL shouldInvalidate = NO;
/*
Insert validation logic here. Set 'shouldInvalidate' to YES in order to stop the timer
*/
if (shouldInvalidate) {
[timer invalidate];
}
}
Assuming that Score is a reference to a label, or something that can display text, you could call it like this:
[self newGameWithStartingScore:25];
This way, you can modify it as needed.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to make a periodic call to a method in objective c?
I am making an app where when the user touches the screen, the following method is called:
- (void)explode:(int)x
The user only has to touch the screen once, but I want the method to be called repeatedly every 0.1 seconds for 100 times, and then it should stop being called.
Is there a way of setting up a 'temporary' timer like this on a method where an integer is being passed?
You could pass a counter and the 'x' as into the timer's userInfo. Try this:
Create the timer in the method that's catching the touch event and pass a counter and the int 'x' into the userInfo:
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithCapacity:2];
[userInfo setValue:[NSNumber numberWithInt:x] forKey:#"x"];
[userInfo setValue:[NSNumber numberWithInt:0] forKey:#"counter"];
[NSTimer timerWithTimeInterval:0.1
target:self
selector:#selector(timerMethod:)
userInfo:userInfo
repeats:YES];
Create the timer method, check the userInfo's number count, and invalidate the timer after 100 times:
- (void)timerMethod:(NSTimer *)timer
{
NSMutableDictionary *userInfo = timer.UserInfo;
int x = [[userInfo valueForKey:#"x"] intValue];
// your code here
int counter = [[userInfo valueForKey:#"counter"] intValue];
counter++;
if (counter >= 100)
{
[timer invalidate];
}
else
{
[userInfo setValue:[NSNumber numberWithInt:x] forKey:#"x"];
[userInfo setValue:[NSNumber numberWithInt:counter] forKey:#"counter"];
}
}
Please also see the Apple docs on NSTimer:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html
I have this code to change the number in the NSString every five seconds.
How will I keep the numbers running in a loop? It now runs from 1 to 19 ,and stops at the last one (19) with a SIGABRT on the line: label.text = ...
How can I start with the first number displayed (0), before the first timer fires?
Here is the code:
-(IBAction) rotate3
{
NSString *number = [self.dayArray description];
NSArray *array = [[NSArray alloc] initWithObjects: #"0", #"1", #"2",..., #"19",nil];
number = #"0" ;
numberCount++ ;
self.dayArray = array;
[array release];
label.text = [NSString stringWithFormat:#"Day: %# ", [dayArray objectAtIndex :numberCount ]];
}
//and the timer
- (void)viewDidLoad
{
timer=[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(rotate3 )userInfo:nil repeats:YES];
}
Here is my answers:
1)I think, at the last one (19), the numberCount is 20 (numberCount++ ;).
2)Just set the value before scheduling the timer.
add this to your .h file, in your interface (that is, if it isn't already there)
{
NSInteger numberCount
}
Then in your viewDidLoad method, initialize numberCount and the label:
numberCount = 0;
label.text = #"0";
And in your time method, replace:
numberCount++
with
if(numberCount++ > 19)
numberCount = 0;
What is the "number" NSString used for, b.t.w.?
Why have dayArray?
why not something like
label.text = [NSString stringWithFormat:#"Day: %d", numberCount++];
if (numberCount>19) numberCount = 0;
I don't know what you have number count initialized to it should probably be -1 and also reinitialized to -1 . if you wish to iterate thru "Day: 0" ... "Day: 19"
It's not clear.
You could change the -(void)viewDidLoad timer to not repeat
timer=[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(rotate3 )userInfo:nil repeats:NO];
then, conditionally set it up again in the rotate3 method if you still want to change the text 5 seconds later.
try this:
#pragma mark - timer callback
-(IBAction)rotate3
{
[label1 setText:[dayArray objectAtIndex:numberCount]];
numberCount++;
if (numberCount >= [dayArray count])
numberCount = 0;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
dayArray = [[NSArray alloc] initWithObjects:#"0",#"1",#"2",#"3", nil];
[label1 setText:[dayArray objectAtIndex:0]];
numberCount = 1;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(rotate3) userInfo:nil repeats:YES];
// Do any additional setup after loading the view, typically from a nib.
}
I have written the program, which chooses a random element from the array.
Once I press the button "Start", how do I loop that code?
I would like, that once a button "Start" is pressed, a new element from the array is chosen and written in the text field every 5 seconds.... Thanks for the answer.
#implementation MARandom
- (IBAction)Start:(id)sender {
NSArray *tones;
tones = [NSArray arrayWithObjects: #"F#0", #"Gb0", #"G0", #"G#0",#"Ab0",#"A0",#"A#0",#"Bb0",#"B0",
#"C1",#"C#1",#"Db1",#"D1",#"D#1",#"Eb1",#"E1",#"F1",#"F#1",#"Gb1",#"G1",#"G#1",#"Ab1",#"A1",#"A#1",#"Bb1",#"B1",
#"C2",#"C#2",#"Db2",#"D2",#"D#2",#"Eb2",#"E2",#"F2",#"F#2",#"Gb2",#"G2",#"G#2",#"Ab2",#"A2",#"A#2",#"Bb2",#"B2",
#"C3",#"C#3",#"Db3",#"D3",#"D#3",#"Eb3",nil];
i= (arc4random() % 48);
NSString *Tone;
Tone = [tones objectAtIndex: i];
[TextField setStringValue:(NSString *)Tone];
}
Please try this:
- (IBAction)Start:(id)sender {
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(updateTextFieldWithRandomNumber)
userInfo:nil
repeats:YES];
}
-(void)updateTextFieldWithRandomNumber{
NSArray *tones;
tones = [NSArray arrayWithObjects: #"F#0", #"Gb0", #"G0", #"G#0",#"Ab0",#"A0",#"A#0",#"Bb0",#"B0",
#"C1",#"C#1",#"Db1",#"D1",#"D#1",#"Eb1",#"E1",#"F1",#"F#1",#"Gb1",#"G1",#"G#1",#"Ab1",#"A1",#"A#1",#"Bb1",#"B1",
#"C2",#"C#2",#"Db2",#"D2",#"D#2",#"Eb2",#"E2",#"F2",#"F#2",#"Gb2",#"G2",#"G#2",#"Ab2",#"A2",#"A#2",#"Bb2",#"B2",
#"C3",#"C#3",#"Db3",#"D3",#"D#3",#"Eb3",nil];
i= (arc4random() % 48);
NSString *Tone;
Tone = [tones objectAtIndex: i];
[TextField setStringValue:(NSString *)Tone];
}
and also consider preparing the array at one place rather than the code that will be repeatedly called, perhaps at viewDidLoad.
Note: untested code, but should work.
I got an NSArray with 5 pictures. I want to display them one after the other in a loop.
My code :
NSArray *tabImage = [[NSArray alloc] init];
tabImage = [[NSArray arrayWithObjects:
[UIImage imageNamed:#"picto_1.png"],
[UIImage imageNamed:#"picto_2.png"],
[UIImage imageNamed:#"picto_3.png"],
[UIImage imageNamed:#"picto_4.png"],
[UIImage imageNamed:#"picto_5.png"],
nil] retain];
int var = 0;
var = indexPath.row;
for (int var = 0; var < 20; var++) {
pictoImage.image = [tabImage objectAtIndex:(var % 5)];
}
I got the same picture all the time.
Thanks for help.
I’m guessing pictoImage is an UIImageView. In that case look at the class reference, specifically the animationImages properties.
pictoImage.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"picto_1.png"],
[UIImage imageNamed:#"picto_2.png"],
[UIImage imageNamed:#"picto_3.png"],
[UIImage imageNamed:#"picto_4.png"],
[UIImage imageNamed:#"picto_5.png"],
nil];
// How many seconds it should take to go through all images one time.
pictoImage.animationDuration = 5.0;
// How many times to repeat the animation (0 for indefinitely).
pictoImage.animationRepeatCount = 4;
[pictoImage startAnimating];
You are not giving the framework time to actually render the images to the window.
All your updates are being coalesced into one "setNeedsDisplay" call. On the next iteration of the run loop, the image view will be rendered using the last image that you set in the loop.
If pictoImage is an UIImageView, #Hagelin's answer is the best way to go. Now, if pictoImage is not an UIImageView object then you will have to take a different approach and that definitely is not a loop.
Set an NSTimer with a desired time interval and invoke a method that updates pictoImage iterating over the tabImages. It should be something like this :-
- (void)setup {
...
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(updatePictoImage:)
userInfo:nil
repeats:YES];
...
}
- (void)updatePictoImage:(NSTimer*)theTimer {
static int i = 0;
if ( i > 20 ) {
pictoImage.image = [tabImages objectAtIndex:(i % 5)];
} else {
[theTimer invalidate];
}
}
This should update the pictoImage every 2 seconds with images in tabImages.
You don't print anything.
You are overriding the contents of your pictoImage 20 times in a row, leaving it with the last assignment when var is 19, so it should be picto_4.png.
Also, the whole var declaration doesn't make much sense at all... first you set it to 0, then you set it to indexPath.row, and in the loop it is completely redefined....