我有一个为 ipad 设计的 IOS 应用程序。在一个页面中,我向用户显示了一份报告,该报告需要在 UIScrollView 内的屏幕上呈现 5000 个 UILabel。这会导致应用程序由于内存不足而崩溃。我知道 UITableView 具有按需加载内容的功能。如何使滚动视图仅呈现某些内容,并在滚动发生时删除不可见的内容并添加应该可见的内容?
3 回答
我终于实现了动态内容加载。我实现的方法是scrollViewDidScroll。在这个方法中,我通过以下方式确定了滚动方向
bool isUp = (currentOffset.y > lastScrollOffset);
然后我通过以下方法确定了可见的内容矩形。
CGRect visibleContentRect;
visibleContentRect.origin = scrollView.contentOffset;
visibleContentRect.size = scrollView.bounds.size;
然后我有一个视图元素数组,每个元素都知道它在滚动视图中的位置,因为它们的框架被设置了。长话短说,每次滚动发生时,我都会确定其框架与可见内容框架相交或包含的视图。我将这些视图添加到滚动视图中。我还确定了那些消失的并将它们从滚动视图中删除,我还将这些视图设置为 nil 并重新创建它们。一旦调用 [scrollView addSubview:view]方法,视图就会在内存中获得更多空间,因为它变得可见。[view removeFromSuperView]方法不会释放该空间。这就是为什么将视图设置为 nil 并重新创建它是必要的。
您应该重新循环(即重用)标签,就像表格视图循环其表格单元格一样。这有时被称为“平铺”子视图。平铺允许您显示超出内存容量的内容。
我建议观看 WWDC 2012 Session 104。本次会议的教程创建了一个照片应用程序,可以在 UIScrollView 中平铺图像视图。虽然照片应用程序滚动内容页面,而不是项目网格,但我认为视频可能与您的应用程序相关。
以下是适用于您的具体案例的教程的简要概述:
(1.) 声明跟踪您的标签的 iVar:
NSMutableSet *recycledLabels;
NSMutableSet *visibleLabels;
(2.) 实现一个获取可重用标签的方法:
- (UILabel *)dequeueRecycledLabel;
(3.) 实现一个平铺的方法:
- (void)tileLabels; // this will add/remove labels from the scroll view
(4.) 设置滚动视图的委托并在 scrollViewDidScroll: 委托方法中调用 tileLabels
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self tileLabels];
}
WWDC 视频将帮助您填写我认为适用于您的案例的详细信息。但是,您必须进行大量即兴创作才能使其适用于您的具体情况。这可能并不容易;但它是可行的。
在视频的最后,讨论了使用 CATileLayer 进行平铺。老实说,我没看懂那部分。但我认为它不适用于您的情况,因为您没有显示大图像。
有什么方法可以重新配置它以使用带有自定义行的表格视图,也许是由多个标签组成的行?该模型以非常自然的方式支持按需加载和资源重用......
也许您可以更具体地了解您的屏幕布局?