UIScrollView-InfiniteScroll 1.3.0

UIScrollView-InfiniteScroll 1.3.0

测试测试
语言语言 Obj-CObjective C
许可 MIT
发布上次发布2022年8月

Andrej MihajlovAndrej Mihajlov 维护。



  • Andrej Mihajlov

UIScrollView+InfiniteScroll

作为 UIScrollView 的类别实现无限滚动。

请注意,演示应用中使用的演示内容是公开可用的,由 hn.algolia.com 和 Flickr 提供。它们可能不合适。

Swizzling

请注意,本类别 swizzleUIScrollView 上的 setContentOffsetsetContentSize 方法。

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 直接使用指示器的框架,所以请先确保自定义指示器视图已设置好尺寸。例如 UIImageViewUIActivityIndicatorView 会自动调整大小,因此不需要为它们设置框架。

贡献者

请参阅 CHANGES

归属

演示应用程序图标来自 PixelResort