arrays - 从文件夹中的图像创建一个数组并随机呈现给定数量的图像(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)/."];
这会产生一个路径数组(请参阅文档)。运行代码时这个数组的值是多少?是否找到任何路径?
// 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];
你有一个路径数组,索引它不会产生UIImage
. 阅读文档中的创建图像对象。UIImage
// 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
文档... 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
创建一个新元素,然后该方法 返回这个新数组。此代码忽略返回值,从而丢弃新数组...NSArray
但是,您没有NSArray
but an 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 的工作方式。如果在研究和设计新解决方案时遇到问题,请针对该新问题提出新问题。您可以包含对这个问题的引用,以便帮助您的人可以追溯历史。
推荐阅读
- r - countrycode 包没有将 cown 转换为 iso3c
- javascript - 如何阻止用户从我的页面复制纯文本以及下载我帖子中的任何图像,他也不能右键单击页面?
- javascript - 使用 ?:(javascript 中的条件运算符)的函数解释
- php - 相当复杂的 PHP 到 Twig 字符串的转换
- angular - Angular-cli 在窗口 7 中安装错误
- android - 如何重命名从图库中检索到的图片并用新名称保存
- c# - 如何在没有视觉派生的情况下从另一个 WinForm 派生?
- javascript - 如何打印 jquery JSON 数据?
- angular - Angular - Renderer2:如何设置没有值的属性?
- scala - 使用 scala/spark 进行数据治理