使用 Apple 的 PhotoScroller 示例预加载附加图像
我正在尝试修改Apple的PhotoScroller示例,但遇到了无法解决的问题。
基本上,PhotoScroller 最初在本地数组中加载一堆图像。我尝试修改它并更改为从 URL 动态请求图像文件。一旦用户滚动到下一页,它将从新的 URL 获取下一张图像。
为了提高性能,我想预加载下一页,这样用户在滚动到下一页时就不需要等待图像下载。一旦下一页位于当前页面,之后的页面将被加载等等...
我不太确定如何实现这一点,我希望有人可以告诉我该怎么做。
这是我的自定义代码:(请参考Apple的PhotoScroller示例中的完整代码)
tilePage方法:(它将在开始时以及每次用户滚动scrollView时调用)
- (void)tilePages
{
// Calculate which pages are visible
CGRect visibleBounds = pagingScrollView.bounds;
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex = MIN(lastNeededPageIndex, [self imageCount] - 1);
// Recycle no-longer-visible pages
for (ImageScrollView *page in visiblePages) {
if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
[recycledPages addObject:page];
[page removeFromSuperview];
}
}
[visiblePages minusSet:recycledPages];
// add missing pages
for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
if (![self isDisplayingPageForIndex:index]) {
ImageScrollView *page = [self dequeueRecycledPage];
//ImageScrollView *nextpage = [self dequeueRecycledPage];
if (page == nil) {
page = [[[ImageScrollView alloc] init] autorelease];
}
[self configurePage:page forIndex:index];
[pagingScrollView addSubview:page];
[visiblePages addObject:page];
}
}
}
配置页面索引和内容:
- (void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index
{
//set page index
page.index = index;
//set page frame
page.frame = [self frameForPageAtIndex:index];
//Actual method to call image to display
[page displayImage:[self imageAtIndex:index]];
NSLog(@"index: %i", index);
}
从URL获取图像:
- (UIImage *)imageAtIndex:(NSUInteger)index {
NSString *string1 = [NSString stringWithString:@"http://abc.com/00"];
NSString *string2 = [NSString stringWithFormat:@"%d",index+1];
NSString *string3 = [NSString stringWithString:@".jpg"];
NSString *finalString = [NSString stringWithFormat:@"%@%@%@",string1,string2,string3];
NSLog(@"final string is: %@", finalString);
NSURL *imgURL = [NSURL URLWithString: finalString];
NSData *imgData = [NSData dataWithContentsOfURL:imgURL];
return [UIImage imageWithData:imgData];
}
谢谢帮忙! 劳伦斯
I am trying to modify Apple's PhotoScroller example and I encountered a problem that I couldn't solve.
Basically, the PhotoScroller originally loaded a bunch of image in an array locally. I try to modify this and change to it request an image file dynamically from an URL. Once the user scroll to the next page, it will fetch the next image from a new URL.
In order to improve the performance, I wanted to preload the next page so user doesn't need to wait for the image being downloaded while scrolling to the next page. Once the next page is on current page, the page after that will be loaded and so on...
I'm not quite sure how I can achieve this and I hope someone can show me what to do.
Here is my custom code: (Please refer the full code from Apple's PhotoScroller example)
tilePage method: (It will be call at the beginning and every time when user did scroll the scrollView)
- (void)tilePages
{
// Calculate which pages are visible
CGRect visibleBounds = pagingScrollView.bounds;
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex = MIN(lastNeededPageIndex, [self imageCount] - 1);
// Recycle no-longer-visible pages
for (ImageScrollView *page in visiblePages) {
if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
[recycledPages addObject:page];
[page removeFromSuperview];
}
}
[visiblePages minusSet:recycledPages];
// add missing pages
for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
if (![self isDisplayingPageForIndex:index]) {
ImageScrollView *page = [self dequeueRecycledPage];
//ImageScrollView *nextpage = [self dequeueRecycledPage];
if (page == nil) {
page = [[[ImageScrollView alloc] init] autorelease];
}
[self configurePage:page forIndex:index];
[pagingScrollView addSubview:page];
[visiblePages addObject:page];
}
}
}
To configure page index and content:
- (void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index
{
//set page index
page.index = index;
//set page frame
page.frame = [self frameForPageAtIndex:index];
//Actual method to call image to display
[page displayImage:[self imageAtIndex:index]];
NSLog(@"index: %i", index);
}
To fetch image from URL:
- (UIImage *)imageAtIndex:(NSUInteger)index {
NSString *string1 = [NSString stringWithString:@"http://abc.com/00"];
NSString *string2 = [NSString stringWithFormat:@"%d",index+1];
NSString *string3 = [NSString stringWithString:@".jpg"];
NSString *finalString = [NSString stringWithFormat:@"%@%@%@",string1,string2,string3];
NSLog(@"final string is: %@", finalString);
NSURL *imgURL = [NSURL URLWithString: finalString];
NSData *imgData = [NSData dataWithContentsOfURL:imgURL];
return [UIImage imageWithData:imgData];
}
Thanks for helping!
Lawrence
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用并发操作来依次获取图像。使用 NSOperations,您可以设置依赖链,以便在后台以串行方式加载图像,或者可以同时下载它们。
大图像的问题在于,即使将它们保存在文件系统中,也需要一个“启动”时间来渲染图像。此外,在 PhotoScroller 中,Apple 通过为每个细节级别预先平铺所有图像来“作弊”。 Apple 没有提供在 PhotoScroller 中仅渲染 Plain ole JPEG 的方法,因此除非您可以预平铺,否则它对您没有任何用处。
如果您好奇,您可以通过仔细阅读 github 上的 PhotoScrollerNetwork 项目来了解如何下载多个图像并将它们预平铺到临时文件中。
You can use concurrent operations to fetch images one after another. Using NSOperations, you can set a dependency chain so images are loaded in a serial fashion in the background, or you can have them all downloaded concurrently.
The problem with large images is that even though you save them in the file system, there is a "startup" time to get the images rendered. Also, in PhotoScroller, Apple "cheats" by having all the images pre tiled for each level of detail. Apple provides no way to render just a Plain ole JPEG in PhotoScroller, so unless you can pre tile it will be of no use to you.
If you are curious, you can see how to both download multiple images and pre tile them into a temporary file by perusing the PhotoScrollerNetwork project on github.