UIScrollView+InfiniteScroll
作为 UIScrollView 的类别实现无限滚动。
![]() |
![]() |
![]() |
请注意,演示应用中使用的演示内容是公开可用的,由 hn.algolia.com 和 Flickr 提供。它们可能不合适。
Swizzling
请注意,本类别 swizzle 了 UIScrollView
上的 setContentOffset
和 setContentSize
方法。
Swift 包管理器
使用 GitHub 仓库 URL 添加新包
https://github.com/pronebird/UIScrollView-InfiniteScroll
然后在源代码中导入模块
import UIScrollView_InfiniteScroll
CocoaPods
在上面的 Podfile 中添加以下行:
pod 'UIScrollView-InfiniteScroll', '~> 1.3.0'
Objective-C
#import <UIScrollView_InfiniteScroll/UIScrollView+InfiniteScroll.h>
或者,如果使用模块
@import UIScrollView_InfiniteScroll;
Swift
在您的桥接头文件中添加以下行
#import <UIScrollView_InfiniteScroll/UIScrollView+InfiniteScroll.h>
Carthage
在您的 Cartfile 中添加以下行
github "pronebird/UIScrollView-InfiniteScroll" ~> 1.3.0
Objective-C
#import <UIScrollView_InfiniteScroll/UIScrollView+InfiniteScroll.h>
或者,如果使用模块
@import UIScrollView_InfiniteScroll;
Swift
import UIScrollView_InfiniteScroll
Examples
该组件附带用 Swift 编写的示例应用程序。
如果您使用 CocoaPods,可以通过运行来尝试
pod try UIScrollView-InfiniteScroll
Documentation
http://pronebird.github.io/UIScrollView-InfiniteScroll/
基础知识
为了启用无限滚动,您需要使用 addInfiniteScrollWithHandler
提供处理程序块。您提供的块在每个无限滚动组件检测到需要提供更多数据时执行。
处理程序块的目的执行异步任务,通常是网络或数据库获取,并更新您的滚动视图或滚动视图子类。
自身在主队列上调用,因此请确保将任何长时间运行的任务移至后台队列。收到新数据后,通过添加新的行和部分更新表格视图,然后调用 finishInfiniteScroll
以完成无限滚动动画并重置无限滚动组件的状态。
在 viewDidLoad
中安装处理程序块是个好地方。
确保所有与 UIKit 或无限滚动提供的方法的交互都在主队列上发生。在 Objective-C 中使用 dispatch_async(dispatch_get_main_queue, { ... })
或者在 Swift 中使用 DispatchQueue.main.async { ... }
以在主队列上运行 UI 相关调用。
很多人在使用处理程序块内部的外部对表格视图或集合视图的引用时出错。不要这样做。这会导致循环引用。相反,使用作为处理程序块的第一个参数传递的滚动视图或滚动视图子类实例。
Objective-C
// setup infinite scroll
[tableView addInfiniteScrollWithHandler:^(UITableView* tableView) {
// update table view
// finish infinite scroll animation
[tableView finishInfiniteScroll];
}];
Swift
tableView.addInfiniteScroll { (tableView) -> Void in
// update table view
// finish infinite scroll animation
tableView.finishInfiniteScroll()
}
集合视图的怪癖
UICollectionView.reloadData
会导致偏移量重置。如果可能,请使用 UICollectionView.performBatchUpdates
。
Objective-C
[self.collectionView addInfiniteScrollWithHandler:^(UICollectionView* collectionView) {
[collectionView performBatchUpdates:^{
// update collection view
} completion:^(BOOL finished) {
// finish infinite scroll animations
[collectionView finishInfiniteScroll];
}];
}];
Swift
collectionView.addInfiniteScroll { (collectionView) -> Void in
collectionView.performBatchUpdates({ () -> Void in
// update collection view
}, completion: { (finished) -> Void in
// finish infinite scroll animations
collectionView.finishInfiniteScroll()
});
}
按编程方式启动无限滚动
您可以使用 beginInfiniteScroll(forceScroll)
方法将无限滚动流程重用于加载数据或获取更多数据。一般情况下,在 viewDidLoad
方法中加载初始数据很好,但这完全取决于您来决定。
当 forceScroll
参数设置为 true
时,无限滚动组件会尝试向下滚动以显示指示视图。请注意,如果用户正在与滚动视图交互,则不会发生滚动。
Objective-C
[self.tableView beginInfiniteScroll:YES];
Swift
tableView.beginInfiniteScroll(true)
防止无限滚动
有时您可能需要阻止无限滚动继续进行。例如,如果您的搜索API没有更多结果,不断发起新的请求或显示加载指示符是没有意义的。
Objective-C
[tableView setShouldShowInfiniteScrollHandler:^BOOL (UITableView *tableView) {
// Only show up to 5 pages then prevent the infinite scroll
return (weakSelf.currentPage < 5);
}];
Swift
// Provide a block to be called right before a infinite scroll event is triggered.
// Return YES to allow or NO to prevent it from triggering.
tableView.setShouldShowInfiniteScrollHandler { _ -> Bool in
// Only show up to 5 pages then prevent the infinite scroll
return currentPage < 5
}
无缝预加载数据
理想情况下,您希望内容无缝流动,永远不显示加载器。无限滚动提供了一个选项,可以指定在用户到达滚动视图底部之前开始预加载器的偏移量(以点为单位)。
在每次加载的结果数量和足够的偏移量之间取得适当的平衡,应该会给用户带来不错的体验。您很可能需要根据自己的内容和设备尺寸推出这二者的组合公式。
// Preload more data 500pt before reaching the bottom of scroll view.
tableView.infiniteScrollTriggerOffset = 500;
自定义指示器
您可以使用自定义指示器来替代默认的 UIActivityIndicatorView
。
自定义指示器必须是 UIView
的子类,并实现以下方法
@objc func startAnimating()
@objc func stopAnimating()
Swift
let frame = CGRect(x: 0, y: 0, width: 24, height: 24)
tableView.infiniteScrollIndicatorView = CustomInfiniteIndicator(frame: frame)
请参阅自定义指示器视图的示例实现
目前 InfiniteScroll 直接使用指示器的框架,所以请先确保自定义指示器视图已设置好尺寸。例如 UIImageView
或 UIActivityIndicatorView
会自动调整大小,因此不需要为它们设置框架。
贡献者
请参阅 CHANGES
归属
演示应用程序图标来自 PixelResort。