【问题标题】:Catch event in view from another class从另一个类中捕获事件
【发布时间】:2015-10-13 11:39:51
【问题描述】:

我有一个带有请求的异步任务,我在 Item 类中每 3 秒获取一次产品。

class Item: NSManagedObject {
    var is_fetching:Bool = false;

    func fetchProducts(q: String) {
        let task = session.dataTaskWithRequest(urlRequest, completionHandler: {
              (data, response, error) in
              self.is_fetching = true;
              //some code

              if ((response as! NSHTTPURLResponse).statusCode == 202) {
                  sleep(3)
                  self.fetchProducts(q)
                  return
              }
              if ((response as! NSHTTPURLResponse).statusCode == 200) {
                  self.is_fetching = false;
              }
          })
          task.resume()
      }
}

我有UITableViewController,我在其中显示来自响应的数据。状态码为 200 时如何更新单元格:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:
        indexPath) as! CartTableViewCell
    if item.is_fetching {
        cell.fetchIndicator.startAnimating();
    } else {
        cell.fetchIndicator.stopAnimating();
        cell.fetchIndicator.hidden = true;
    }
}

【问题讨论】:

    标签: ios swift delegates swift2


    【解决方案1】:

    您可以通过几种方式做到这一点。

    NSNotificationCenter(最简单)。

    您可以发布通知,这将触发控制器的方法。看起来像这样:

    // if response.code == 200
    NSNotificationCenter.defaultCenter().postNotificationName("kSomeConstatnString", object: nil)
    ...
    // in viewDidLoad of your controller:
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateTable", object: nil)
    // you also need implement updateTable() func inside your controller
    // or if you need just update table
    NSNotificationCenter.defaultCenter().addObserver(self.tableView, selector: "reloadData", object: nil)
    // do not forget to delete observer (for instance in -deinit method)
    NSNotificationCenter.defaultCenter().removeObserver(self) 
    // or tableView. also you can specify for which selector, if you use couple of them.
    

    委托模式。

    您可以描述您的协议,让您的控制器实现此协议并将其作为实例保存在您的模型对象中。然后只需从委托中调用方法。详情here.

    阻止回调。

    为动作创建块并从您的模型中调用它。例如:

    // inside controller
    model.refreshCallback = { Void in
      self.tableView.reloadData() // or whatever
    }
    // inside model
    var refreshCallback: (() -> Void)?
    ...
    // if result.code == 200
    if let callback = refreshCallback {
      callback()
    }
    

    【讨论】:

      【解决方案2】:

      使用UITableView 的重新加载功能之一,也许:

      func reloadRowsAtIndexPaths(_ indexPaths: [NSIndexPath],
                 withRowAnimation animation: UITableViewRowAnimation)
      

      这将导致它再次询问有问题的单元格。确保在主线程上执行此操作。

      【讨论】:

      • 但是如何在 Item 类中获取 UITableView 重载功能?
      • 这是您必须解决的问题,具体取决于您的应用程序的结构。也许在 Item 中设置一个委托,您可以在获取完成时调用一个方法。或者在 AppDelegate 子类中有一个引用表视图的变量。
      • 尝试使用 fetchresultcontroller ,这样处理起来会更有效率。
      猜你喜欢
      • 1970-01-01
      • 2015-02-12
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      • 2020-05-04
      • 2011-10-14
      • 2017-02-02
      • 2018-10-30
      相关资源
      最近更新 更多