在 iPad 上浏览多个全屏图像的性能

发布于 2024-12-03 13:00:43 字数 410 浏览 0 评论 0原文

我需要让用户通过点击来前后导航不同的图像(从 10 到 20)。
所有图像都是 1024x768 JPG,因此我不需要调整它们的大小或转换它们。
它们之间没有动画(我将使用 removeFromSuperView 和 addSubView 切换它们)。
我想要的只是避免加载时间或无响应的触摸,所以我实际上正在考虑这些可能的解决方案:

  1. 点击时单独加载每个图像;
  2. 加载 3 张图像:上一张、实际图像和下一张;
  3. 加载包含所有图像的数组或 uiviewimage 并迭代它;

我将避免使用 imageNamed,并使用 imageWithContentOfFile 或 imageWithData。
您认为哪种解决方案是最好的?
解决方案 1. 和 3. 会带来一些性能问题吗?

I need to let user navigate back and forward through different images (from 10 to 20) with a tap.
All the images are 1024x768 JPG's so I don't need to resize or transform them.
There are no animations between them (I'll switch them with a removeFromSuperView and addSubView).
All I want is avoid loading time or unresponding touch, so I actually was thinking about these possible solutions:

  1. Load each image singularly on tap;
  2. Load 3 images: previous, actual and next one;
  3. Load an array or a uiviewimage with all the images and iterate through it;

I will avoid imageNamed and I'll use imageWithContentOfFile or imageWithData.
Which solution do you think is the best one?
Could solutions 1. and 3. bring some performance issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温馨耳语 2024-12-10 13:00:43

方法 1 会很好:iOS 设备可以非常快地加载全屏图像。特别是当你的图像没有 Alpha 时。这取决于图像,但经典 png 大约需要 0.05 秒。这意味着如果您在点击后必须进行更改,特别是在图像之间进行淡入淡出过渡时,用户将不会注意到等待时间。

如果用户可以滚动图像,事情会变得更加困难。在这种情况下,我建议使用 UITableView。它们的行为类似于 UISCrollView,并且可以快速、平稳地加载/卸载页面。

要获得水平表格视图,您可以使用完美运行的代码: https://github.com/alekseyn/EasyTableView

Method 1 will be good : iOS devices can load full screen images really fast. Especially if your images don't have alpha. It will depends on images but it takes around 0.05 seconds for a classic png. This means that users will not notice the waiting time if you have to change after a tap especially if you had a fade transition between images.

Things can get harder if user can scroll through images. In this case, I would advise to use UITableView. They behave like UISCrollView and they load/unload pages fastly and smoothly.

To get an horizontal table view, you can use this code which works perfectly : https://github.com/alekseyn/EasyTableView

野味少女 2024-12-10 13:00:43

如果图像数量的上限是 20,只需预加载 UIImage 数组,并在响应触摸时设置 UIImageView.image 属性 - 不必担心交换视图,重用单个 UIImageView 就可以了。

我不会担心性能,除非上限提高得多 - 如果确实如此,像选项 2 这样的动态缓存将是更好的选择,但需要更多的编程。

如果您担心面向应用程序商店的 iPad 应用程序的性能,请务必记住在第一代 iPad 上进行测试,因为在第一代 iPad 上性能有了很大的提升。

If your upper limit for number of images is 20, just preload an array of UIImages, and set the UIImageView.image property on response to touch - don't worry about swapping views, reusing a single UIImageView will be fine.

I wouldn't worry about performance unless the upper limit rises much higher - if it does, a dynamic cache like option 2 would be a better choice, but more programming.

If you are concerned about performance in an iPad application destined for the app store, always remember to test on a first generation iPad, since there was a major performance jump after the original.

痴情 2024-12-10 13:00:43

我以前确实这样做过。对于大图像,您必须小心记忆。我最初将所有图像加载到 NSArray 中,但遇到了内存警告和崩溃。

我的实现使用带有分页功能的 UIScrollView。我必须数组,一个包含所有图像名称,另一个是可变的并且仅包含一些 UIImageView。我记录滚动视图所在的当前“页面”,当我落在图像上时,我确保可变数组包含该图像及其两侧的两个图像(并从数组中删除任何其他图像)。

此实现的问题是您必须不断从磁盘读取图像,这在主线程上会很慢。所以当我最初创建 UIImageViews 时,我向它们添加了一个 UIActivityIndi​​cator 。然后,我将 UIImageViews 数组传递给后台的一个方法,该方法实际加载 UIImage,然后使相应的 UIImageView 在主线程上设置图像,如下所示:

// called before you try to load an image in a background thread
    [imageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

// called in the background thread after you load the image from disk
    [imageView performSelectorOnMainThread:@selector(setImage:) withObject:fullImage waitUntilDone:NO];`


    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        UIImageView *imageView = (UIImageView *)object;
        [[imageView viewWithTag:1] removeFromSuperview]; // this is the activity indicator
        [imageView removeObserver:self forKeyPath:@"image"];
    }

I have actually done this before. With large images, you are going to have to be careful with memory. I originally loaded all of my images into an NSArray but I experienced memory warning and crashes.

My implementation uses a UIScrollView with paging. I have to arrays, one contains all of the image names and the other is mutable and contains only a few UIImageViews. I record the current 'page' that the scroll view is on, and when I land on an image I ensure that the mutable array contains that image and two images on either side of it (and remove any other images from the array).

The problem with this implementation is that you keep having to read images from disk which will be slow on the main thread. Sooo when I initially create the UIImageViews I add a UIActivityIndicator to them. Then, I pass my array of UIImageViews to a method in the background that actually loads the UIImage and then makes the respective UIImageView set the image on the main thread like so:

// called before you try to load an image in a background thread
    [imageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

// called in the background thread after you load the image from disk
    [imageView performSelectorOnMainThread:@selector(setImage:) withObject:fullImage waitUntilDone:NO];`


    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        UIImageView *imageView = (UIImageView *)object;
        [[imageView viewWithTag:1] removeFromSuperview]; // this is the activity indicator
        [imageView removeObserver:self forKeyPath:@"image"];
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文