Let's see if we can help you along:
-(void)displayImagesInRandomOrder {
// Obtain set number of attempts
imageArrayLength = 20; // arbitrary choice in this example
// Build array from all (120) .PNG images in folder
NSArray *_imageArray = [[NSBundle mainBundle] pathsForResourcesOfType:@".png" inDirectory:@"(Folder directory)/."];
This produces an array of paths (see the documentation). What is the value of this array when you run your code? Are any paths found?
// Create a random integer for each of the (120) images in the array
int randomIndex = arc4random_uniform((uint32_t) _imageArray.count);
// Select an image from the array using the random number
UIImage *randomImage = [_imageArray objectAtIndex:randomIndex];
You have an array of paths, indexing it won't produce a UIImage
. Read Creating Image Objects in the UIImage
documentation.
// Add the UIImage to a UIImageView and display it on the screen
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:randomImage];
// Set position of the image
tempImageView.contentMode = UIViewContentModeScaleAspectFit;
}
There is no code here to select 20 elements. When you want to select N different cards at random from a deck of playing cards how do you do it? Now read the NSArray
documentation... HTH
Addendum After Your Comment & Question Edit
You've made some good progress, but as you say it still doesn't work. Let's take a look at your new code:
Here is the first of my revised methods to build an array of 20 images selected at random from the folder:
NSMutableArray *imageQueue;
There are a couple of problems here, one design, one programming:
- Never use a global variable just to return a value from a method
- This declares a variable,
imageQueue
, which is capable of storing a reference to an NSMutableArray
. All objects need to be created, you don't create an array here, and this variable will have the value nil
– i.e. it references nothing.
Try a design along the lines of:
- (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength
{
// create a mutable array to hold the images
NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
// your code to fill the array
...
// return the final array, by convention immutable (NSArray) so copy
return [imageQueue copy];
}
Back to your code:
- (void)buildArrayOfRandomImages {
// Build array of pathnames to images in folder
NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:@"(Folder directory)"];
There is nothing wrong with this per se, but have you checked (using the debugger or logging statements) that pathArray
contains any elements? While (Folder Directory)
is a valid name for a folder did you actually call your folder this name?
// Obtain preset number of attempts
imageQueueLength = 20;
// Create image queue (new array) of predetermined length
// use a loop to add correct number of images to image queue
for(int i = 1; i <= imageQueueLength; i++) {
// Select an integer at random for each image in the array of pathnames
int randomIndex = arc4random_uniform((uint32_t) [pathArray count]);
Again there is nothing wrong with this per se, it produces a random index for you. However it could produce the same index more than once, do you not want 20 different images?
My playing card analogy obviously was detailed enough: How do you typically select N random cards from a deck? You shuffle the deck and then deal the required N cards off the top. Take another look at NSArray
...
// Add images to the image queue
[imageQueue arrayByAddingObject:[UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]]];
}
}
This doesn't do what you expect. The method arrayByAddingObject:
is from NSArray
and it creates a new NSArray
from an existing one and the new element, the method then returns this new array. This code ignores the return value, thus discarding the new array...
However you don't have an NSArray
but an NSMutableArray
, so you don't need to create a new array each time you need to add an object to your mutable array. Take a look at NSMutableArray
again...
Here is the second method:
- (void)displayImageFromArray {
// Add the UIImage to a UIImageView and display it on screen
UIImageView *imageView = [[UIImageView alloc] initWithImage:[imageQueue objectAtIndex:imageCount]];
// Set screen position of image
imageView.contentMode = UIViewContentModeScaleAspectFit;
// increment count every time method is called
imageCount++;
}
First this method should have a declaration like:
- (void) displayImage:(NSUInteger)imageCount fromArray:(NSArray *)imageQueue
i.e. pass in the required data, don't use global variables. Or better yet just:
- (void) displayImage:(UIImage)theImage
as there is no need to pass the array & index and if defined this way the image doesn't need to come from an array at all.
However the above declarations are probably insufficient – your method as written won't display any images and the additional code to do that may require a further argument as well.
Why won't it display any images? An UIImageView
will only display its image on screen if it is part of the current view hierarchy. Now that is another whole topic in itself, so unless you've omitted code for brevity you've some more reading to do.
Postscript
Don't try to extend this question further, that is not how SO works. If in researching and designing your new solution you hit an issue ask a new question on that new issue. You can include a reference to this question so people assisting you can trace back the history.