0

我正在使用这个:https ://github.com/nicklockwood/SwipeView

我在我的应用程序的 2 个不同的地方使用它。

  1. 屏幕上的 30x30 图像大约 100kb 文件大小,这部分没有问题
  2. 屏幕上的 150x150 图像 1-3mb 文件大小,这些是 ios 相机拍摄的照片。

第二次调用 swipeViewCurrentItemIndexDidChange 方法时,应用程序滞后约 0.5 秒,这不会给用户带来良好的体验。我知道它正在发生,因为图像正在加载,我试图改进这个过程,但我没有成功。我希望加快速度,以便用户感觉不到项目加载。图像是从设备加载的,不涉及互联网连接。

我知道这些操作一直在图片库和 Facebook 应用程序中完成,没有滞后。所以我的代码或我正在使用的这个库有问题。

http://pastebin.com/XyCaRaig

4

4 回答 4

1

屏幕上的 150x150 图像 1-3mb 文件大小,这些是 ios 相机拍摄的照片。

这是我加快速度的两个建议。

建议一

ALAssetsLibrary库将在单独的线程上运行。我建议在主线程中做 UI 相关的事情。使用-performSelectorOnMainThread:dispatch_sync(dispatch_get_main_queue()ALAssetsLibrary块内将解决您的问题。

例子:

   [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *needToStop) {

        dispatch_sync(dispatch_get_main_queue(), ^{

          UIImage *image = [UIImage imageWithCGImage:result.defaultRepresentation.fullScreenImage];
          //do UI stuff here.

    }); }]; }

   failureBlock:^(NSError *error) {
               NSLog(@"%@",error.description);
  }];

或者

   [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *needToStop) {

             UIImage *image = [UIImage imageWithCGImage:result.defaultRepresentation.fullScreenImage];
            [self performSelectorOnMainThread:@selector(usePhotolibraryimage:) withObject:image waitUntilDone:NO];

      }]; }

   failureBlock:^(NSError *error) {
               NSLog(@"%@",error.description);
  }];

- (void)usePhotolibraryimage:(UiImage *)myImage{

    //do UI stuf here.
}

建议二

使用 AlAssetaspectRatioThumbnail代替fullResolutionImage高性能

dispatch_sync(dispatch_get_main_queue(), ^{

    CGImageRef iref = [myasset aspectRatioThumbnail];
    //CGImageRef iref = [myasset thumbnail];
    UIImage *image = [UIImage imageWithCGImage:iref];

 });
于 2014-07-10T08:23:43.263 回答
1
if(self.pictures[index] != NULL) //(self.pictures[index] != NULL) //(button == nil) //(self.currentArray[index][2] != NULL)
    {
    UIImage *image = [UIImage imageWithContentsOfFile:self.pictures[index]];
    button = [UIButton buttonWithType:UIButtonTypeCustom];

    NSString *machineName = [MasterClass whichMachine];
    if ([machineName isEqual:@"ipad"]) {
        button.frame = CGRectMake(0.0, 0.0, 220, 220);
    } else if ([machineName isEqual:@"iphone4"])  {
        button.frame = CGRectMake(0.0, 0.0, 120, 120);
    } else if ([machineName isEqual:@"ipod"])  {
        button.frame = CGRectMake(0.0, 0.0, 120, 120);
    }
    else{
        button.frame = CGRectMake(0.0, 0.0, 140, 140);
    }
        [button setBackgroundImage:image forState:UIControlStateNormal];
        .....

我注意到您在小范围内使用全分辨率图像,并且从 CPU/GPU 加载会花费大量不必要的资源。你很幸运没有崩溃。我建议您压缩按钮上显示的图像大小,并在必要时以全分辨率显示。这就是 Facebook 的做法。

于 2014-07-14T16:00:46.610 回答
0

我不知道 Swipeview,但我会尝试两件事,具体取决于可以用它做什么。

1-修改插件预加载的图像数量或在将它们提供给插件之前自行加载它们。如果您在屏幕上显示 3 张图像并且用户可以在不分页的情况下双向滚动,您可能需要预加载 10-20 张图像

2-使用后台线程,浏览用户滑动范围内的所有图像(再次,10-20 图像范围应该足够了)从库中加载图像,将其缩小并将其保存在缓存文件夹中。它应该只从该文件夹加载已经优化的图像以向用户显示。

于 2014-07-09T23:25:35.900 回答
0

Facebook 应用程序使用https://github.com/rs/SDWebImage加载图像...

首先你有滞后,因为你没有重用 SwipeViewDataSource 中的视图。你需要做这样的事情

- (UIView *)swipeView:(__unused SwipeView *)swipeView viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{
    UIButton *button = (UIButton *)view;
    if(!button) {
        button = [UIButton buttonWithType:UIButtonTypeCustom];
    }

    NSString *imageFile = self.pictures[index];
    NSLog(@"Image that will be loaded : %@",imageFile);

    if(imageFile) {
        UIImage *image = [UIImage imageWithContentsOfFile:imageFile];

        NSString *machineName = [MasterClass whichMachine];
        if ([machineName isEqual:@"ipad"]) {
            button.frame = CGRectMake(0.0, 0.0, 220, 220);
        } else if ([machineName isEqual:@"iphone4"])  {
            button.frame = CGRectMake(0.0, 0.0, 120, 120);
        } else if ([machineName isEqual:@"ipod"])  {
            button.frame = CGRectMake(0.0, 0.0, 120, 120);
        } else{
            button.frame = CGRectMake(0.0, 0.0, 140, 140);
        }

        [button setBackgroundImage:image forState:UIControlStateNormal];
        button.tag = 100 + index;

        [button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
    }

    return button;
}

然后,主要问题是图像解压缩...系统需要在屏幕上显示之前对图像进行解压缩,并且需要在后台完成(如果您不想滞后)...解压缩图像有点棘手所以尝试使用 SDWebImage 因为它会为您解压缩背景中的图像;)

要使用 SDWebImage 加载本地文件,请参见:https ://github.com/rs/SDWebImage/issues/153

如果您想了解一些有关此问题的信息,可以查看有关 cocoanetics 的旧帖子:http: //www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/

于 2014-07-14T16:10:06.327 回答