Фикс iOS тянуть, чтобы обновить sh анимацию - PullRequest
1 голос
/ 04 февраля 2020

Вот мой код для Refre sh Control. (Код был обновлен с помощью всего кода 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 не будет обновлен.

enter image description here

Ответы [ 5 ]

4 голосов
/ 04 февраля 2020

Добавление refre sh control в качестве подпредставления может быть проблемой. У UITableView теперь есть свойство для элемента управления refre sh. Здесь у вас есть описание из документации Apple, как вы должны это реализовать: https://developer.apple.com/documentation/uikit/uirefreshcontrol

2 голосов
/ 04 февраля 2020

Вы немедленно завершаете анимацию после вызова fetchAirports(), который, как я полагаю, является асинхронным c сетевым запросом или чем-то, что имеет задержку для завершения.

Если вы хотите подождать, пока аэропорты выбираются и таблица обновляется, добавьте закрытие завершения для этой функции. Что-то в этом роде:

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

А потом в вашем refre sh метод:

@objc func refresh(sender: UIRefreshControl) {
    airportRequest.fetchAirports(completion: { [weak self] in
        self?.sender.endRefreshing()
    })
}
1 голос
/ 04 февраля 2020

Попробуй ..

@objc func refresh(sender: UIRefreshControl) {
        refreshControl.beginRefreshing()
        airportRequest.fetchAirports(completion: { [weak self] in
            self?.tableView?.reloadData()
            refreshControl?.endRefreshing()
     })
  } 
0 голосов
/ 04 февраля 2020

Поместите точку останова в didUpdateAirports и посмотрите, откуда (и когда) он вызывается. Анимация должна останавливаться только после вызова endRefreshing.

Возможно, в данных нет изменений, поэтому, возможно, вы получаете кэшированный ответ, который приведет к очень быстрому вызову endRefreshing.

Вы также можете вставить простую инструкцию print («сейчас заканчивается анимация»), чтобы увидеть, как это происходит в реальном времени.

0 голосов
/ 04 февраля 2020

Вы можете вызвать этот метод после вставки новых данных в таблицу.

refreshControl.endRefreshing()
...