在网络呼叫后绑定到UIRefreshControl

时间:2016-04-01 13:50:58

标签: ios swift uirefreshcontrol rx-swift

我是RxSwift的新手,我想知道如何能够“反应性地”将UIRefreshControl与UITableView一起使用而不是通常的创建目标方式,并手动调用beginRefreshing()和{{1} }。

例如,假设我正在从API加载一些字符串:

endRefreshing()

class TableViewController: UITableViewController { var data : [String] = [] let db = DisposeBag() override func viewDidLoad() { super.viewDidLoad() refreshControl = UIRefreshControl() //I don't want to use //refreshControl?.addTarget(self, action: #selector(getData), forControlEvents: .ValueChanged) //Do something to refreshControl.rx_refreshing? } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) let str = data[indexPath.row] cell.textLabel?.text = str return cell } //MARK: - Requests private func getData() { let myData = MyAPI.getData() //Returns Observable<[String]> myData .subscribe({ [weak self] (event) in switch event { case .Next(let strings): self?.data = strings self?.tableView.reloadData() break case .Error(let err): print(err) break case .Completed: break } // self?.refreshControl?.endRefreshing() }) .addDisposableTo(db) } } 发送一些字符串值的请求,如何绑定MyAPI以调用refreshControl并在网络请求完成(或错误)时停止刷新?我需要绑定到refreshControl.rx_refreshing吗?

1 个答案:

答案 0 :(得分:7)

RxSwift的示例应用程序提供了一个有趣的类来处理这种逻辑:ActivityIndicator

进入ActivityIndicator后,将rx_refreshing绑定到请求的代码变得非常简单。

let activityIndicator = ActivityIndicator()

override func viewDidLoad() {
  super.viewDidLoad()

  refreshControl = UIRefreshControl()

  // When refresh control emits .ValueChanged, start fetching data
  refreshControl.rx_controlEvent(.ValueChanged)
    .flatMapLatest { [unowned self] _ in
      return self.getData()
      .trackActivity(activityIndicator)
    }
    .subscribeNext { [unowned self] strings in
      self.data = strings
      self.tableView.reloadData()
    }
    .addDisposableTo(db)

  // Bind activity indicator true/false to rx_refreshing
  activityIndicator.asObservable()
    .bindTo(refreshControl.rx_refreshing)
    .addDisposableTo(db)
}

// getData only needs to return an observable, subscription is handled in viewDidLoad
private func getData() -> Observable<[String]> {
  return myData = MyAPI.getData() //Returns Observable<[String]>
}