【问题标题】:Fix iOS pull to refresh animation修复 iOS 拉动刷新动画
【发布时间】:2020-05-20 07:03:29
【问题描述】:

这是我的刷新控件代码。 (代码已更新为整个 ViewController 代码以便更好地理解)

import UIKit

class AirportTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, AirportRequestDelegate {


    @IBOutlet weak var airportTable: UITableView!
    var airportRequest = AirportRequest()
    var airportList = [AirportDetail]()
    var refreshControl = UIRefreshControl()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "Airport List"
        airportTable.delegate = self
        airportRequest.delegate = self
        airportRequest.fetchAirports()
        airportTable.dataSource = self
        refreshControl.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged)
        airportTable.addSubview(refreshControl)

    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return airportList.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let myCell = airportTable.dequeueReusableCell(withIdentifier: "airportTableCell", for: indexPath)
        myCell.textLabel?.text = self.airportList[indexPath.row].AirportName
        myCell.detailTextLabel?.text = self.airportList[indexPath.row].StationName
        myCell.accessoryType = .disclosureIndicator
        return myCell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.airportTable.deselectRow(at: indexPath, animated: true)
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if  editingStyle == .delete {
            self.airportList.remove(at: indexPath.row)
            airportTable.deleteRows(at: [indexPath], with: .top)
        }
    }


// The AirportRequestDelegate adds this function and is called once airport list is fetched
    func didUpdateAirports(_ airportRequest: AirportRequest, airports: [AirportDetail]) {

// copies the airport list to a local variable so that it can be used with the tableView delegate functions
        self.airportList = airports

// updating the UI
        DispatchQueue.main.async {
            self.airportTable.reloadData()
            self.refreshControl.endRefreshing()
        }
    }

    @objc func refresh(sender: UIRefreshControl) {
        airportRequest.fetchAirports()
    }


}

在下图中,您可以看到动画没有按预期工作。我该如何解决。最好我希望动画一直持续到 tableView 更新为止。

【问题讨论】:

  • 能否添加执行请求的函数,然后调用委托didUpdateAirports
  • 这里是一个link 指向一个包含整个项目的公共 github 存储库(而不是用大量代码使问题变得混乱)。我相信您将能够重现该问题。感谢您的帮助。

标签: ios swift uitableview pull-to-refresh


【解决方案1】:

将刷新控件添加为子视图可​​能是个问题。 UITableView 现在具有刷新控件的属性。在这里,您有来自苹果文档的描述,您应该如何实现它: https://developer.apple.com/documentation/uikit/uirefreshcontrol

【讨论】:

  • 我认为这不会导致问题中描述的问题。虽然确实使用 tableView 的 refreshControl 属性是更好的做法,但我一直在我的项目中使用 addSubview 没有任何问题(但我现在将开始使用该属性)。
  • 感谢您的更新,但正如 Roberto 所说,我更改了代码以使用该属性,但这并没有影响问题。
  • 我也发现了类似的问题:stackoverflow.com/questions/35391236/…
  • 非常感谢您向我指出这一点,它解决了我的问题。 @Roberto 也感谢您的帮助和耐心。
  • 你能检查一下这个问题吗 --> stackoverflow.com/q/67056902/15466427
【解决方案2】:

您在调用fetchAirports() 后立即结束动画,我认为这是一个异步网络请求或有延迟完成的东西。

如果您想等到获取机场并更新表,请向该函数添加一个完成闭包。类似的东西:

func fetchAirports(@escaping completion: (() -> Void) {
    // Perform the network request and once it finishes, call completion()
    networkRequest() {
        completion()
    }
}

然后在你的刷新方法中:

@objc func refresh(sender: UIRefreshControl) {
    airportRequest.fetchAirports(completion: { [weak self] in
        self?.sender.endRefreshing()
    })
}

【讨论】:

  • 我有一个在 fetchAirports() 函数完成后调用的委托函数。委托函数更新了 tableView,之后我添加了 endRefreshing() 函数,但这也没有解决问题。
  • 你确定 endRefreshing() 函数在 tableView 重新加载之后才被调用吗?
  • 是的,我已经确定了这一点。无论如何,我会用整个代码更新我的问题,以便您有更好的想法。
【解决方案3】:

试试吧..

@objc func refresh(sender: UIRefreshControl) {
        refreshControl.beginRefreshing()
        airportRequest.fetchAirports(completion: { [weak self] in
            self?.tableView?.reloadData()
            refreshControl?.endRefreshing()
     })
  } 

【讨论】:

    【解决方案4】:

    您可以在向表中插入新数据后调用此方法。

    refreshControl.endRefreshing()
    

    【讨论】:

      【解决方案5】:

      在 didUpdateAirports 中放置一个断点并查看从何处(以及何时)调用它。只有在调用 endRefreshing 时,动画才会停止。

      也许数据没有变化,所以也许你得到了一个缓存的响应,这会导致一个非常快速的 endRefreshing 调用。

      您还可以输入一个简单的打印(“现在结束动画”)语句来实时查看它的发生。

      【讨论】:

        猜你喜欢
        • 2011-07-05
        • 1970-01-01
        • 2013-07-09
        • 2020-02-09
        • 2014-03-30
        • 2014-07-09
        • 1970-01-01
        • 2016-07-23
        • 2021-07-07
        相关资源
        最近更新 更多