 |
 |
|
 |
01-09-2009, 05:22 PM
|
#1 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Random Display Text/Image from List
I would appreciate a tutorial on how to display a text string, or image, chosen at random from a pre-defined list. For example, I want a user to be able to push a button and have the phone randomly display one of the following responses "yes", "no", or "maybe". Thanks for any assistance.
|
|
|
01-10-2009, 12:19 AM
|
#2 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 1,064
Rep Power: 2
|
In general, you want to make an array of your (images / strings,) then pick a random number, then grab that Item from the array. Something like this:
Code:
//create the array
NSArray *myArray= [NSArray arrayWithObjects: @"Yes",@"No",@"File Not Found", nil];
//get the length of the array
int length = [myArray count];
//choose an item - C magic happens here :)
int chosen = (float)random() * length /RAND_MAX;
//get that item
NSString *item = [myArray objectAtIndex: chosen];
//print that item
NSLog(@"The item I picked is: %@", item);
That's 4 bits of cocoa magic, and one bit of plain-old C magic.
|
|
|
01-10-2009, 12:24 PM
|
#3 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Quote:
Originally Posted by smasher
In general, you want to make an array of your (images / strings,) then pick a random number, then grab that Item from the array.
|
Hi Smasher. Thanks very much for taking time to respond. I am completely new to programming, so not entirely sure how to integrate this into my app. As a placeholder, I had a button writing a text string to a label field (shown below).
Code:
- (IBAction)hello:(id)sender {
helloLabel.text = @"May the Force Be with You";
}
I tried plunking the code you shared into an IBAction in my Controller.m file, substituting the NSLog line for my helloLabel.text line, but couldn't get it to work. I'm sure this is a simple thing to implement, but it is escaping me.
Thanks again for any assistance.
Last edited by DenVog; 01-10-2009 at 12:33 PM.
|
|
|
01-10-2009, 04:45 PM
|
#4 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
I kept messing with this. Kinda got it to work, but sometimes get the same response several times in a row (i.e. not seeming very random) and am getting "Warning: local declaration of 'myArray' hides instance variable" messages.
I stuck the following in my Controller.h file
Code:
NSArray *myArray;
@ property (nonatomic, retain) NSArray *myArray;
and the following in my Controller.m file
Code:
- (IBAction)hello:(id)sender {
//create the array
NSArray *myArray= [NSArray arrayWithObjects: @"Yes",@"No",@"Maybe", nil];
//get the length of the array
int length = [myArray count];
//choose an item - C magic happens here :)
int chosen = (float)random() * length /RAND_MAX;
//get that item
NSString *item = [myArray objectAtIndex: chosen];
//print that item
helloLabel.text = (@"THe item I picked is: %@", item);
}
hello is a label field that I'm outputting the text to display on screen. Still expect I'm doing something wrong. Help greatly appreciated. Thanks.
|
|
|
01-11-2009, 01:23 AM
|
#5 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 1,064
Rep Power: 2
|
It's always the same result, or sometimes you get the same result twice in a row? Getting duplicates in a row is not surprising - if you flip a coin 30 times, you'll see a lot of HeadHeadHead and TailTailTail.
If you want to get rid of dupes, you'll have to keep track of what the last item chosen was, and pick a new item if you pull a dupe. We could do this with a "do-while" loop.
Code:
- (IBAction)hello:(id)sender {
//"static" means this variable will keeps it value between function calls.
static int lastChosen=0;
//this is the same
NSArray *myArray= [NSArray arrayWithObjects: @"Yes",@"No",@"Maybe", nil];
int length = [myArray count];
int chosen;
//this is a "Do" loop - it repeats as long as the "while" is true.
//we'll keep picking numbers until we get not-a-dupe
do {
chosen = (float)random() * length /RAND_MAX;
} while(chosen==lastChosen);
//this is the same
NSString *item = [myArray objectAtIndex: chosen];
//this is how we combine the two strings
helloLabel.text = [NSString stringWithFormat: @"The item I picked is: %@", item];
//save the value for the next function call
lastChosen=chosen;
}
|
|
|
01-11-2009, 04:52 PM
|
#6 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Quote:
Originally Posted by smasher
If you want to get rid of dupes, you'll have to keep track of what the last item chosen was, and pick a new item if you pull a dupe. We could do this with a "do-while" loop.
|
This certainly makes it seem more random, even if it's technically not.
Should I just ignore the "Warning: local declaration of 'myArray' hides instance variable" messages." that I keep getting?
Thanks again for sharing your knowledge on this. It is a huge help. I really appreciate it.
|
|
|
01-11-2009, 05:58 PM
|
#7 (permalink)
|
|
Senior Member
Join Date: Sep 2008
Posts: 154
Rep Power: 1
|
Quote:
Originally Posted by DenVogel
This certainly makes it seem more random, even if it's technically not.
Should I just ignore the "Warning: local declaration of 'myArray' hides instance variable" messages." that I keep getting?
Thanks again for sharing your knowledge on this. It is a huge help. I really appreciate it.
|
Is that because you defined the array in your header file and your .m??
|
|
|
01-12-2009, 09:08 AM
|
#8 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Quote:
Originally Posted by ipodtouchmaster05
Is that because you defined the array in your header file and your .m??
|
I'm not sure. I tried removing the statements related to myArray from the Controller.h file, but then it doesn't run at all. Here's what I have in there now.
Code:
NSArray *myArray;
@ property (nonatomic, retain) NSArray *myArray;
Thanks again for the assistance. I'm completely new to programming, so I'm sure it's painful answering these n00b questions.
|
|
|
01-12-2009, 11:37 AM
|
#9 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 1,064
Rep Power: 2
|
Quote:
Originally Posted by DenVogel
Should I just ignore the "Warning: local declaration of 'myArray' hides instance variable" messages." that I keep getting?
|
In my code, I put
NSArray *myArray= blah blah blah.
That creates a new array pointer and points it at the array.
If you already have an array pointer, you can just say:
myArray= blah blah blah.
That'll use the array pointer you already have, and fix the warning you were getting. The message you got really means "You already have a variable myArray, and you made another variable called myArray? WTF?"
You can have two variables with the same name - one for the instance and one inside a method - but it's uncommon and can lead to coding mistakes; so the complier warns you
about it.
|
|
|
01-16-2009, 12:39 PM
|
#10 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Quote:
Originally Posted by smasher
"You already have a variable myArray, and you made another variable called myArray? WTF?"
|
I am sorry to keep dragging this thread on, but I'd really like to learn what I'm doing wrong. I am still getting two "warning: local declaration of 'myArray' hides instance variable" errors.
I've tried various ways of renaming or removing statements, but am embarrassed to say I can't figure it out.
Here's all the myArray code in my ViewController.h file
Code:
NSArray *myArray;
@property (nonatomic, retain) NSArray *myArray;
Here's all the myArray code in my ViewController.m file
Code:
@synthesize myArray;
- (IBAction)hello:(id)sender {
static int lastChosen=0;
NSArray *myArray= [NSArray arrayWithObjects:
@"Response 1.",
@"Response 2.", nil];
int length = [myArray count];
int chosen;
{
chosen = (float)random() * length /RAND_MAX;
} while(chosen==lastChosen);
NSString *item = [myArray objectAtIndex: chosen];
helloLabel.text = [NSString stringWithFormat: @"%@", item];
[helloLabel setFont: [UIFont fontWithName:@"Verdana-BoldItalic" size:24]];
lastChosen=chosen;
}
I appreciate the patience, and help. I'm sure it's frustrating getting these newbie questions.
Last edited by DenVog; 01-16-2009 at 02:08 PM.
Reason: reversed .m and .h labels in original post
|
|
|
01-16-2009, 01:43 PM
|
#11 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 1,064
Rep Power: 2
|
I think you have your labels in your post reversed? Maybe you have it right in the files; the .h file as the interface and the property; the .m file has the synthesize and the implementation.
In the .m file, you can replace this:
Code:
NSArray *myArray= [NSArray arrayWithObjects:
@"Response 1.",
@"Response 2.", nil];
with this
Code:
self.myArray= [NSArray arrayWithObjects:
@"Response 1.",
@"Response 2.", nil];
The first one makes a new pointer variable and uses it, the second one uses the property that you set up the the .h file.
|
|
|
01-16-2009, 01:51 PM
|
#12 (permalink)
|
|
Senior Member
Join Date: Sep 2008
Posts: 154
Rep Power: 1
|
Quote:
Originally Posted by DenVogel
I am sorry to keep dragging this thread on, but I'd really like to learn what I'm doing wrong. I am still getting two "warning: local declaration of 'myArray' hides instance variable" errors.
I've tried various ways of renaming or removing statements, but am embarrassed to say I can't figure it out.
Here's all the myArray code in my ViewController.m file
Code:
NSArray *myArray;
@property (nonatomic, retain) NSArray *myArray;
Here's all the myArray code in my ViewController.h file
Code:
@synthesize myArray;
- (IBAction)hello:(id)sender {
static int lastChosen=0;
NSArray *myArray= [NSArray arrayWithObjects:
@"Response 1.",
@"Response 2.", nil];
int length = [myArray count];
int chosen;
{
chosen = (float)random() * length /RAND_MAX;
} while(chosen==lastChosen);
NSString *item = [myArray objectAtIndex: chosen];
helloLabel.text = [NSString stringWithFormat: @"%@", item];
[helloLabel setFont: [UIFont fontWithName:@"Verdana-BoldItalic" size:24]];
lastChosen=chosen;
}
I appreciate the patience, and help. I'm sure it's frustrating getting these newbie questions.
|
dude you ARE declaring that array both in your header and .m! Remove the
NSArray * from that statement in your .m, so your .m should look like this:
Code:
@synthesize myArray;
- (IBAction)hello:(id)sender {
static int lastChosen=0;
myArray= [NSArray arrayWithObjects:
@"Response 1.",
@"Response 2.", nil];
int length = [myArray count];
int chosen;
{
chosen = (float)random() * length /RAND_MAX;
} while(chosen==lastChosen);
NSString *item = [myArray objectAtIndex: chosen];
helloLabel.text = [NSString stringWithFormat: @"%@", item];
[helloLabel setFont: [UIFont fontWithName:@"Verdana-BoldItalic" size:24]];
lastChosen=chosen;
}
|
|
|
01-16-2009, 02:10 PM
|
#13 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Quote:
Originally Posted by smasher
I think you have your labels in your post reversed?
|
Yes. I had my labels reversed. I edited the previous post so it is correct now.
Thanks very much for your help and patience Smasher. That modification has it working with no errors. Thanks again!
|
|
|
02-01-2009, 07:53 PM
|
#14 (permalink)
|
|
Junior Member
Join Date: Feb 2009
Posts: 2
Rep Power: 0
|
Seems to not be random??
I am also a new programmer and every time it runs, I get the same order of answers - I have put 6 values in the array and they appear - 6, 3, 5, 5, 6, 2, 3, 5, 2, 4 ......
I can close the sim, recompile and sure enough they appear in this order everytime.
Any ideas?
==
NSArray *myArray= [NSArray arrayWithObjects: @"1111",@"2222",@"3333",@"4444",@"5555",@"6666" , nil];
int length = [myArray count];
//choose an item - C magic happens here 
int chosen = (float)random() * length /RAND_MAX;
NSString *item = [myArray objectAtIndex: chosen];
lblText.text = [NSString stringWithFormat: @"%@", item];
|
|
|
02-01-2009, 08:19 PM
|
#15 (permalink)
|
|
Junior Member
Join Date: Feb 2009
Posts: 2
Rep Power: 0
|
ok nevermind
I figured it out...
NSArray *myArray= [NSArray arrayWithObjects: @"1111",@"2222",@"3333",@"4444",@"5555",@"6666" , nil];
int chosen = arc4random() % [myArray count];
NSString *item = [myArray objectAtIndex: chosen];
lblText.text = [NSString stringWithFormat: @"%@", item];
|
|
|
02-02-2009, 10:58 AM
|
#16 (permalink)
|
|
Senior Member
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 289
Rep Power: 1
|
Quote:
Originally Posted by PhillipJames
I get the same order of answers
I can close the sim, recompile and sure enough they appear in this order everytime.
|
Thanks for posting this. I had not noticed it, and probably wouldn't until I got a user bug report. Appreciate you posting the fix too!
|
|
|
02-06-2009, 02:28 PM
|
#17 (permalink)
|
|
Junior Member
Join Date: Feb 2009
Posts: 2
Rep Power: 0
|
Hi DenVog, is there any chance you can shere the project files with me? maybe email them? If so, please PM me,
Thanks very much in advance!
|
|
|
02-07-2009, 07:18 PM
|
#18 (permalink)
|
|
Senior Member
iPhone Dev SDK Supporter
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 1,064
Rep Power: 2
|
Quote:
Originally Posted by PhillipJames
I am also a new programmer and every time it runs, I get the same order of answers - I have put 6 values in the array and they appear - 6, 3, 5, 5, 6, 2, 3, 5, 2, 4 ......
I can close the sim, recompile and sure enough they appear in this order everytime.
Any ideas?
|
Yes - random() is actually a pseudorandom number generator. It starts with a "seed" value, and always generates the same set of numbers from that seed. Sooooo... the trick is to pick a different "seed" every time you start the program. The most common way to to do that is by using the current date+time as the seed; then you should get a different sequence every time.
Try this at the beginning of your program; say, in applicationDidFinishLaunching:
srandom (time (0));
BTW, don't get fancy about calling random() more than once, or multiplying two random number to get an even-more-random number, etc - you'd actually be removing randomness, not increasing it.
|
|
|
 |
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
» Advertisements |
|
» Online Users: 258 |
| 25 members and 233 guests |
| amoll, bensj, BostonMerlin, crossfire, dapis, DGuy, Dracor, Groucho, heinrich, idigit, Jeremy1026, Jume, kaleman, lastiko, lildragon, mattjgalloway, mnemonic_fx, odysseus31173, Oliver Drobnik, Opticfibre, shabzcohelp, Sicga, tonylmiller, utopiaplan, wolkje |
| Most users ever online was 779, 05-11-2009 at 09:55 AM. |
» Stats |
Members: 8,229
Threads: 20,197
Posts: 90,213
Top Poster: RickMaddy (2,121)
|
| Welcome to our newest member, jrsiqueira |
|