如何解决根据文件夹中的图片创建数组,并随机显示给定数量的图片Objective-C
我正在尝试从包含大量图像(120)的文件夹中随机显示预定数量的.PNG图像(例如20个)。
这是我基于几个示例得出的代码;我在viewDidLoad中调用此方法。
-(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)/."];
// 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];
// 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;
}
所有帮助/建议都得到了亲切的接待,因为我凝视了太久了。提前非常感谢:)
编辑///
这是我修改后的方法中的第一个方法,用于构建从文件夹中随机选择的20张图像的阵列:
NSMutableArray *imageQueue;
- (void)buildArrayOfRandomImages {
// Build array of pathnames to images in folder
NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:@"(Folder directory)"];
// 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]);
// Add images to the image queue
[imageQueue arrayByAddingObject:[UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]]];
}
}
这是第二种方法:
- (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++;
}
我对此有信心,但是imageQueue数组在buildArrayOfRandomImages
方法中仍然为空。
解决方法
让我们看看能否为您提供帮助:
-(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)/."];
这将生成一个 paths 数组(请参见documentation)。运行代码时此数组的值是什么?找到任何路径了吗?
// 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];
您有一个 paths 数组,对其进行索引不会产生UIImage
。阅读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; }
这里没有代码选择20个元素。当您要从一副扑克牌中随机选择 N 张不同的纸牌时,您该怎么做?现在阅读NSArray
documentation ... HTH
评论和问题后的附录编辑
您已经取得了一些不错的进步,但是正如您所说的那样,它仍然行不通。让我们看看您的新代码:
这是我修改后的方法中的第一个方法,用于构建从文件夹中随机选择的20张图像的阵列:
NSMutableArray *imageQueue;
这里有两个问题,一种设计,一种编程:
- 从不使用全局变量只是为了从方法中返回值
- 这声明了一个变量
imageQueue
,该变量能够存储对NSMutableArray
的引用。所有对象都需要创建,您无需在此处创建数组,并且此变量的值将为nil
–即它不引用任何内容。
尝试以下设计:
- (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];
}
返回您的代码:
- (void)buildArrayOfRandomImages { // Build array of pathnames to images in folder NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:@"(Folder directory)"];
此本身没什么问题,但是您是否已检查(使用调试器或日志记录语句)pathArray
包含任何元素?虽然(Folder Directory)
是文件夹的有效名称,但是您实际上将文件夹称为该名称吗?
// 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]);
同样,此本身没什么问题,它会为您生成一个随机索引。但是,它可能会多次产生相同的索引,您是否要20张不同的图像?
我的扑克牌类比显然很详细:您通常如何从牌组中选择 N 个随机牌?您洗牌,然后在顶部上交易所需的 N 张牌。再看看NSArray
...
// Add images to the image queue [imageQueue arrayByAddingObject:[UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]]]; } }
这没有达到您的期望。方法arrayByAddingObject:
来自NSArray
,它根据现有元素和新元素创建一个 new NSArray
,然后该方法返回这个新数组。该代码将忽略返回值,从而丢弃新数组...
但是,您没有NSArray
却只有NSMutableArray
,因此,每次需要向可变对象添加对象时,都不需要创建新的数组数组。再看看NSMutableArray
...
这是第二种方法:
- (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++; }
首先,此方法应具有如下声明:
- (void) displayImage:(NSUInteger)imageCount fromArray:(NSArray *)imageQueue
即传递所需的数据,不要使用全局变量。还是更好:
- (void) displayImage:(UIImage)theImage
因为不需要传递数组和索引,并且如果以这种方式定义,则图像根本不需要来自数组。
但是,以上声明可能不够用-您编写的方法将不会显示任何图像,并且为此做的其他代码也可能需要进一步的论证。
为什么它不显示任何图像? UIImageView
仅在属于当前视图层次结构的一部分时才会在屏幕上显示其图像。现在,这本身就是另外一个完整的主题,因此,除非您为了简洁起见省略了代码,否则还需要阅读更多内容。
后记
不要尝试进一步扩展这个问题,那不是SO的工作方式。如果在研究和设计新解决方案时遇到问题,请就该新问题提出一个新问题。您可以包括对此问题的参考,以便协助您的人可以追溯历史。
,@CRD,根据要求,我不再更新问题,但想向您展示我的进度。再次非常感谢您将我带到这里!
[正如您明智地建议的那样,我将把此线程限制为创建随机选择的图像数组,因为显示它们是一个完全不同的问题。]
解决方案1 (似乎可以工作,但不太优雅):
- (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength {
// Build array of pathnames to images in folder (nil directory was the only one that actually worked for me)
NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:nil];
// Create a mutable array to hold the images
NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
// Fill the imageQueue array using pathnames
for(int i = 1; i <= imageQueueLength; i++) {
// Select a random integer
int randomIndex = arc4random_uniform((uint32_t) [pathArray count]);
// Use the random integer to select a pathname and create an image object
UIImage *image = [UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]];
// Ensure all elements are unique
if (![imageQueue containsObject:image]) {
// Add image to the image queue
[imageQueue addObject:image];
} else {
i--; // ensure the array is the correct length
}
}
// Return the final array,by convention immutable (NSArray) so copy
return [imageQueue copy];
}
解决方案2:(更优雅,但需要导入GameplayKit
框架,该框架也必须链接到项目-请参见https://stackoverflow.com/a/47404462/11137617)
- (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength {
// Build array of pathnames to images in folder
NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:nil];
//Create a shuffled copy of pathArray
NSArray *shuffledPaths;
shuffledPaths = [pathArray shuffledArray];
// Create a mutable array to hold the images
NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
// Fill the image queue array using pathnames
for(NSUInteger i = 1; i <= imageQueueLength; i++) {
UIImage *image = [UIImage imageWithContentsOfFile:[shuffledPaths objectAtIndex:(i - 1)]];
[imageQueue addObject:image];
}
// Return the final array,by convention immutable (NSArray) so copy
return [imageQueue copy];
}
解决方案3:(避免使用单独的数组改组方法导入GameplayKit
,该方法主要基于以下内容:https://stackoverflow.com/a/56656/11137617,其本身是基于Fisher-Yates改组的@CRD建议)
- (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength {
// Build array of pathnames to images in folder
NSString *directory = nil;
NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:directory];
//Create a shuffled copy of pathArray
NSArray *shuffledPaths;
shuffledPaths = [self shuffleArray:pathArray];
// qCreate a mutable array to hold the images
NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
// Fill the image queue array using pathnames
for(NSUInteger i = 1; i <= imageQueueLength; i++) {
UIImage *image = [UIImage imageWithContentsOfFile:[shuffledPaths objectAtIndex:(i - 1)]];
[imageQueue addObject:image];
}
// Return the final array,by convention immutable (NSArray) so copy
return [imageQueue copy];
}
数组改组方法:
- (NSArray *) shuffleArray:(NSArray*)array {
NSMutableArray *shuffledArray = [NSMutableArray arrayWithArray:array];
for (NSUInteger i = 0; i < [shuffledArray count] - 1; ++i) {
NSInteger remainingCount = [shuffledArray count] - i;
NSInteger exchangeIndex = i + arc4random_uniform((u_int32_t )remainingCount);
[shuffledArray exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
}
return [shuffledArray copy];
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。