首页 > 解决方案 > 从文件夹中的图像创建一个数组并随机呈现给定数量的图像(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方法中仍然是空的。

标签: arraysobjective-cimage

解决方案


让我们看看我们是否可以帮助您:

-(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;

这里有几个问题,一个设计,一个编程:

  1. 永远不要仅仅为了从方法返回值而使用全局变量
  2. 这声明了一个变量 ,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

但是,您没有NSArraybut 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 的工作方式。如果在研究和设计新解决方案时遇到问题,请针对该新问题提出新问题。您可以包含对这个问题的引用,以便帮助您的人可以追溯历史。


推荐阅读