【问题标题】:Add a ActivityIndicator to the bottom of UITableView while loading加载时在 UITableView 底部添加一个 ActivityIndi​​cator
【发布时间】:2017-07-16 09:20:57
【问题描述】:

我想在显示最后一个单元格时将 ActivityIndi​​cator 添加到 UITableView 的底部,同时我正在获取更多数据,然后在获取数据时隐藏它。

所以我滚动到底部 -> 显示的最后一行 -> 获取数据时微调器开始旋转 -> 获取数据,隐藏微调器 -> 添加到 tableview 的新数据。

关于如何实现这一点的任何提示?

谢谢 ;)

【问题讨论】:

    标签: ios uitableview swift3 uiactivityindicatorview


    【解决方案1】:

    添加此功能

     func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let lastSectionIndex = tableView.numberOfSections - 1
        let lastRowIndex = tableView.numberOfRows(inSection: lastSectionIndex) - 1
        if indexPath.section ==  lastSectionIndex && indexPath.row == lastRowIndex {
           // print("this is the last cell")
            let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
            spinner.startAnimating()
            spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(44))
    
            self.tableview.tableFooterView = spinner
            self.tableview.tableFooterView?.isHidden = false
        }
    }
    

    并且 tableFooterView 应该在数据加载时隐藏。

    【讨论】:

    • 永远不要使用固定尺寸值,因为屏幕尺寸不同
    • 什么是tableView_category?
    • tableview_category 是包含行的默认 tableView。我明白了,这个例子就像一个魅力
    • 它可以工作,但加载到最后并没有停止
    • 加载在底部时没有停止,因此多次运行服务
    【解决方案2】:

    斯威夫特 5

     func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let lastSectionIndex = tableView.numberOfSections - 1
        let lastRowIndex = tableView.numberOfRows(inSection: lastSectionIndex) - 1
        if indexPath.section ==  lastSectionIndex && indexPath.row == lastRowIndex {
           // print("this is the last cell")
            let spinner = UIActivityIndicatorView(style: .medium)
            spinner.startAnimating()
            spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(44))
    
            self.tableview.tableFooterView = spinner
            self.tableview.tableFooterView?.isHidden = false
        }
    }
    

    【讨论】:

    • 工作就像一个魅力
    【解决方案3】:

    更新 2020 Swift 5、Xcode 11

    我使用了@Ayaz Akbar 的解决方案,效果很好。它只是需要一些改进。以下是我根据需要采用它的方式。

    如果没有要加载的项目,则删除加载指示器

    由于您每次进入项目末尾时都添加加载指示器,因此您将不再向表视图数据源添加新项目。此时您需要移除加载指示器。我正在使用自定义UITableViewDataSource,每次收到新数据时都会调用它的完成处理程序。我还保留了var newCount 以跟踪新项目的数量。所以这是我在视图控制器中隐藏活动指示器的操作:

    private lazy var dataSource: CustomTableViewDataSource = {
        return CustomTableViewDataSource(query: CustomQuery) { [unowned self] (result) in
        // For the initial load I needed a standard activity indicator in the center of the screen
        self.stopMainActivityIndicatorIfNeeded()
    
        switch result {
        case .success(()):
            if self.dataSource.newCount > 0 {
                self.tableView.reloadData()
            } else {
                // Hide the tableFooterView, respectively the activity indicator
                self.tableView.tableFooterView = nil
            }
        case .failure(let error):
            self.showError(error)
        }
        }
    }()
    

    这是我更新的UITableView 委托方法:

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let lastSectionIndex = tableView.numberOfSections - 1
        let lastRowIndex = tableView.numberOfRows(inSection: lastSectionIndex) - 1
        if indexPath.section ==  lastSectionIndex && indexPath.row == lastRowIndex && dataSource.newCount > 0 {
            let spinner = UIActivityIndicatorView(style: .gray)
            spinner.frame = CGRect(x: 0.0, y: 0.0, width: tableView.bounds.width, height: 70)
            spinner.startAnimating()
            tableView.tableFooterView = spinner
        }
    }
    

    【讨论】:

    • 初始化程序 CustomTableViewDataSource(query: CustomQuery) 中发生了什么?也许您可以在答案中添加 CustomTableViewDataSource 的代码?
    • 初始化器是这样的? init(query: CustomQuery, completionHandler: @escaping (Result<(), Error>) -> Void) { ... }
    • 类似的东西。只需根据您的需要调整 Result 枚举。我的完成处理程序如下所示:@escaping (Result<Void>) -> Void。如果您想了解有关此技术和数据源的更多信息,请查看:codelabs.developers.google.com/codelabs/…
    • 我需要将其更改为 @escaping (Result<Void, Void>) -> Void 以免出现语法错误。
    【解决方案4】:

    一种方法是添加一个带有 UIActivityIndi​​catorView 的自定义单元格。你可以把它放在一个单独的部分。有很多方法可以做到这一点。

    或者你看看这个:https://github.com/evnaz/ENFooterActivityIndicatorView

    【讨论】:

    • 我看看
    • 我不想为此使用第三方库,并且给定的示例是用 Obj-C 编写的
    • 您不必使用它。您可以查看它以了解其工作原理,并在需要时快速编写。
    【解决方案5】:
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    
        let total = (self.array.count )
        if (indexPath.item + 1) == (self.array.count ){
            self.limit = Int(self.limit+20) // table item render limit
            if total < limit {
                let spinner = UIActivityIndicatorView(style: .gray)
                spinner.startAnimating()
                spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(44))
    
                self.myTableView.tableFooterView = spinner
                self.myTableView.tableFooterView?.isHidden = false
            }
        }
    }
    

    【讨论】:

      【解决方案6】:

      您可以将子视图添加到UITableView 并在用户滚动到底部时显示。

      我不得不在多个UIScrollViews 上实现相同的东西,最后为它创建了一个DSL

      还创建了pod
      您可以查看源代码或根据需要使用 pod。

      https://github.com/salmaanahmed/PullToRefreshDSL

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        • 2015-08-01
        相关资源
        最近更新 更多