ios - 使用延迟加载在 ScrollView 上加载图像

标签 ios iphone uiscrollview uiimageview lazy-loading

我正在开发一个应用程序,我需要在其中的 ScrollView 中加载近 211 张图像。 我所做的是将图像转换为二进制格式 (NSData) 并将它们保存在核心数据中。然后检索它们并将它们填充到 ScrollView 上。

它确实有效,但有时它会抛出“内存警告”。

我了解到延迟加载是一种实现此目的的方法。但是,我并不完全了解它是如何完成的。

例如,加载 ScrollView 中当前可见图像的前/后 3 或 5 张图像。

任何人都可以通过一个简单的例子帮助我,这将帮助我从头开始理解吗?并会给我指明正确的方向。

感谢您的宝贵时间。

最佳答案

嗯,不需要将图像存储到核心数据中。只需将所有图像 URL 放入 NSMutableArray 并尝试根据您的要求使用以下代码。希望这对您有帮助。

试试这个代码 -

    friendsScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 470, 320, 100)];
    friendsScrollView.contentSize = CGSizeMake([meetUPFrndNameArray count] * 95,50);
    friendsScrollView.backgroundColor = [UIColor clearColor];
    friendsScrollView.delegate = self;
    [self.view addSubview:friendsScrollView];

    int imageX = 25,imageY = 20;
    int backImageX = 10, backImageY = 10;

    int flag = 0;

    for (int i = 0; i < [meetUPFrndPhotoArray count]; i++) {

        flag ++;

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
        NSString *documentsDirectory = paths[0];
        NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:meetUPFrndPhotoArray[flag-1]];
        UIImage *img1 = [UIImage imageWithContentsOfFile:savedImagePath];

        if (!img1 || [UIImagePNGRepresentation(img1) length] <=0)
        {
            id path = meetUPFrndPhotoArray[flag-1];
            path = [path stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
            NSURL *url = [NSURL URLWithString:path];
            NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:url, [NSString stringWithFormat:@"%d", flag], nil];

            [self performSelectorInBackground:@selector(loadImageInBackground:) withObject:arr];

            UIImageView *frndBackgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(backImageX, backImageY, 80, 80)];
            frndBackgroundImage.image = [UIImage imageNamed:@"friend_image_background.png"];
            frndBackgroundImage.backgroundColor = [UIColor clearColor];
            frndBackgroundImage.layer.borderWidth = 2.0;
            frndBackgroundImage.layer.masksToBounds = YES;
            frndBackgroundImage.layer.shadowOffset = CGSizeMake(0, 1);
            frndBackgroundImage.layer.shadowOpacity = 1;
            frndBackgroundImage.layer.shadowRadius = 1.2;
            frndBackgroundImage.layer.cornerRadius = 5.0;
            frndBackgroundImage.layer.borderColor = [[UIColor clearColor] CGColor];
            [friendsScrollView addSubview:frndBackgroundImage];

            UIImageView *friendImage = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, 50, 50)];
            friendImage.tag = flag;
            friendImage.image = [UIImage imageNamed:@"ic_user.png"];
            [friendsScrollView addSubview:friendImage]; 
        }
        else
        {
            UIImageView *frndBackgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(backImageX, backImageY, 80, 80)];
            frndBackgroundImage.image = [UIImage imageNamed:@"friend_image_background.png"];
            frndBackgroundImage.backgroundColor = [UIColor clearColor];
            frndBackgroundImage.layer.borderWidth = 2.0;
            frndBackgroundImage.layer.masksToBounds = YES;
            frndBackgroundImage.layer.shadowOffset = CGSizeMake(0, 1);
            frndBackgroundImage.layer.shadowOpacity = 1;
            frndBackgroundImage.layer.shadowRadius = 1.2;
            frndBackgroundImage.layer.cornerRadius = 5.0;
            frndBackgroundImage.layer.borderColor = [[UIColor clearColor] CGColor];
            [friendsScrollView addSubview:frndBackgroundImage];

            UIImageView *friendImage = [[UIImageView alloc] initWithFrame:CGRectMake(imageX, imageY, 50, 50)];
            friendImage.tag = flag-1;
            friendImage.image = img1;
            [friendsScrollView addSubview:friendImage];

        }

        backImageX = backImageX + 80 + 10;
        backImageY = 10;

        imageX = imageX + 50 + 25 + 15;
        imageY = 20;

    }

此处 meetUPFrndPhotoArray 包含图像 URL。

用于在后台下载图像 -

- (void) loadImageInBackground:(NSArray *)urlAndTagReference{

     NSData *imgData = [NSData dataWithContentsOfURL:urlAndTagReference[0]];
     UIImage *img = [[UIImage alloc] initWithData:imgData];

     NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:img, urlAndTagReference[1], nil];

     [self performSelectorOnMainThread:@selector(assignImageToImageView:) withObject:arr waitUntilDone:YES];
  }

用于将下载的图像分配给特定的 imageView -

- (void) assignImageToImageView:(NSArray *)imgAndTagReference{

      for (UIImageView *checkView in [friendsScrollView subviews] ){

          if ([imgAndTagReference count] != 0) {

               if ([checkView tag] == [imgAndTagReference[1] intValue]){
                   [checkView setImage:imgAndTagReference[0]];

                   NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
                   NSString *documentsDirectory = paths[0];
                   NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:meetUPFrndPhotoArray[[imgAndTagReference[1] intValue]-1]];
                   UIImage* imageToSave = [checkView image];
                   NSData *imageData = UIImagePNGRepresentation(imageToSave);
                   [imageData writeToFile:savedImagePath atomically:NO];
               }
          }
     }
}

请告诉我这是否对您有帮助。提前致谢。祝您一切顺利。

关于ios - 使用延迟加载在 ScrollView 上加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19665718/

相关文章:

ios - 重新单击按钮后程序不会更新

ios - 根据swift 4中排序的文本安排其余两个标签

ios - UITextField 和键盘通知 - 奇怪的顺序

ios - 更改 UIScrollView 内容大小

iphone - 如何动态调整UIScrollview的大小

ios - 如何使用 UIActivityViewController 共享经度和纬度

ios - 根据行数动态更改 TextView 高度

iOS:保持 View 不变或在各种 ViewController 之间传递 View

iphone - 当应用程序激活时关闭本地通知

ios - 没有平移手势的 UIScrollView 水平滚动