xcode iOS UIScrollView 延迟加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11750164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 01:05:21  来源:igfitidea点击:

iOS UIScrollView Lazy Loading

iphoneiosxcodeuiscrollviewlazy-loading

提问by nfoggia

i was just wondering if someone could explain this code for me so i can actually learn from it. I am trying to make my app have a scroller that scrolls left to right with loads of pictures (from internet) but the thing is, it must have lazy loading. so i did some tutorials and figured out how to do it but i truly don't understand it. So i was hoping some kind soul would explain how to lazy load step by step

我只是想知道是否有人可以为我解释这段代码,这样我才能真正从中学习。我试图让我的应用程序有一个滚动条,可以从左到右滚动加载大量图片(来自互联网),但问题是,它必须具有延迟加载。所以我做了一些教程并想出了如何去做,但我真的不明白。所以我希望有好心人会解释如何逐步延迟加载

This is the code i had learned from the tutorials:

这是我从教程中学到的代码:

-(void)scrollViewDidScroll:(UIScrollView *)myScrollView {
/**
 *  calculate the current page that is shown
 *  you can also use myScrollview.frame.size.height if your image is the exact size of your scrollview
 */
int currentPage = (myScrollView.contentOffset.y / currentImageSize.height);

// display the image and maybe +/-1 for a smoother scrolling
// but be sure to check if the image already exists, you can do this very easily using tags
if ( [myScrollView viewWithTag:(currentPage +1)] ) {
    return;
}
else {
    // view is missing, create it and set its tag to currentPage+1
}

/**
 *  using your paging numbers as tag, you can also clean the UIScrollView
 *  from no longer needed views to get your memory back
 *  remove all image views except -1 and +1 of the currently drawn page
 */
for ( int i = 0; i < currentPages; i++ ) {
    if ( (i < (currentPage-1) || i > (currentPage+1)) && [myScrollView viewWithTag:(i+1)] ) {
        [[myScrollView viewWithTag:(i+1)] removeFromSuperview];
    }
}

}

}

回答by CedricSoubrie

About Lazy loading on scrollView, I would greatly advised to use UITableView instead. Apple did a great job with performance on this component.

关于在 scrollView 上延迟加载,我强烈建议改用 UITableView。苹果在这个组件的性能方面做得很好。

You can have them horizontal (see this EasyTableView code, it works great) and stop the page mode if you want a continuous scroll (pagingEnabled = NO;) so you'll be able to get the behavior you are looking for.

您可以将它们水平放置(请参阅此EasyTableView 代码,效果很好)并停止页面模式(如果您想要连续滚动)(pagingEnabled = NO;),这样您就可以获得您正在寻找的行为。

回答by sppalkia

Lazy loading is basically fetching large pieces of data (lets say images in this example) only when you need them. In your code, you have a delegate method that is called when you scroll a UIScrollView.

延迟加载基本上是在您需要时才获取大量数据(在本例中可以说是图像)。在您的代码中,您有一个在滚动 UIScrollView 时调用的委托方法。

The -(void)scrollViewDidScroll:(UIScrollView *)myScrollView function decides when to actually get data. So as your scrolling, you find out where you are in the scroll view (say you have 10 images you want to load-- you want to know if the screen is currently showing image number 1, 2, 3, etc.). This is what the currentPage integer holds.

-(void)scrollViewDidScroll:(UIScrollView *)myScrollView 函数决定何时实际获取数据。因此,当您滚动时,您会发现您在滚动视图中的位置(假设您有 10 个要加载的图像——您想知道屏幕当前是否显示图像编号 1、2、3 等)。这就是 currentPage 整数所保存的内容。

Now that you know which page you're looking at, we want to actually fetch the image.

现在您知道您正在查看哪个页面,我们想要实际获取图像。

if ( [myScrollView viewWithTag:(currentPage +1)] ) {
    return;
}

The code above checks if the image AFTER the image the person is currently looking at exists (hence the currentPage + 1). If it does, we've already fetched it and we quit the function. Otherwise:

上面的代码检查该人当前正在查看的图像之后的图像是否存在(因此 currentPage + 1)。如果是,我们已经获取它并退出该函数。除此以外:

else {
    // view is missing, create it and set its tag to currentPage+1
}

Here, we lazy load the image. This is done, for example, by creating a new thread and downloading the image from a server. We do this while the view is not the currentPage because we don't want the image to "pop in" while the user is scrolling. The view to which we add the image gets a tag (UIView has a "tag" property); we set the tag to currentPage+1, which later allows us to index the view in case we need it.

在这里,我们延迟加载图像。例如,这是通过创建一个新线程并从服务器下载图像来完成的。我们在视图不是 currentPage 时这样做,因为我们不希望图像在用户滚动时“弹出”。我们添加图像的视图获得一个标签(UIView 有一个“标签”属性);我们将标签设置为 currentPage+1,这允许我们在需要时索引视图。

Finally, we have:

最后,我们有:

/**
*  using your paging numbers as tag, you can also clean the UIScrollView
*  from no longer needed views to get your memory back
*  remove all image views except -1 and +1 of the currently drawn page
*/
for ( int i = 0; i < currentPages; i++ ) {
    if ( (i < (currentPage-1) || i > (currentPage+1)) && [myScrollView viewWithTag:(i+1)] )         {
        [[myScrollView viewWithTag:(i+1)] removeFromSuperview];
    }
}

Here, we use our currentPage variable and iterate through all our views by indexing them by the tag we set. If the tag is not one off from the currentPage (remember, we don't want any pop in!) we remove it from the scrollview and free some memory up.

在这里,我们使用 currentPage 变量并通过我们设置的标签索引它们来遍历所有视图。如果标签不是与 currentPage 分开的(记住,我们不希望任何弹出!)我们从滚动视图中删除它并释放一些内存。

Hope that helped.

希望有所帮助。

回答by khalid usman

Perhaps this will help you.

也许这会对你有所帮助。

  1. Downloads the Asynchronous ImageView files from here https://github.com/nicklockwood/AsyncImageView/and include them into your project.

  2. Drag the ImageView on xib file and change it's class to AsynchronousImageView rather than UIImageView

  3. Write this in you .h file

    IBOutlet AsynchronousImageView *_artworkImg;

  4. Write this in your .m file

    [_artworkImg loadImageFromURLString:@"Your Image Url"];

  1. 从这里下载异步 ImageView 文件https://github.com/nicklockwood/AsyncImageView/并将它们包含到您的项目中。

  2. 拖动 xib 文件上的 ImageView 并将其类更改为 AsynchronousImageView 而不是 UIImageView

  3. 把这个写在你的 .h 文件中

    IBOutlet AsynchronousImageView *_artworkImg;

  4. 将此写入您的 .m 文件中

    [_artworkImg loadImageFromURLString:@"你的图片网址"];