如何从Swift中的另一个类访问和刷新UITableView

时间:2016-05-27 21:03:20

标签: ios swift uitableview

我有一个标签栏应用程序和一个标签,其视图控制器由UITableView类控制。我有一个类用于从服务器下载数据,然后将其保存到NSDefaults。从那里我希望该类能够更新表视图,但不知道如何访问表视图的类来更新它。

class updates {

func checkForUpdates() {
    //start on background thread
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] in
        //start contacting database:
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
        let actualVersion = self.contactForUpdates()
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
        if actualVersion > self.defaults.objectForKey("version") as! Int {
            //update data
            if self.downloadUpdates() {
                //update version number
                self.defaults.setObject(actualVersion, forKey: "version")
                //Indicates progress finished
                //self.stopSpinner()
            }
        }//end updates
        else {
            //Indicates progress finished
            //self.stopSpinner()

        }
    }//end background queue
}

}

有两个区域评论//Indicates progress finished,我想从类中运行tableView:

class connectTableVC: UITableViewController {
    ...
}

4 个答案:

答案 0 :(得分:7)

您可以使用protocolNSNotificationCenter

NSNotificationCenter的示例:

从下载数据的UIViewController,您可以在完成下载数据后发布通知,并告诉其他对象有新数据:

NSNotificationCenter.defaultCenter().
                    postNotificationName("newDataNotif", object: nil)

任何其他想要收听此通知的对象都应注册观察(在您的情况下为UITableViewController):

NSNotificationCenter.defaultCenter().
                     addObserver(self, #selector(shouldReload), 
                     name:"newDataNotif", object: nil)

然后你需要实现接收通知时要调用的方法:

func shouldReload() {
  self.tableView.reloadData()
}

请注意,通知也可以发送类型为[NSObject : AnyObject]?的数据示例:

NSNotificationCenter.defaultCenter().
                     postNotificationName("newDataNotif", 
                     object: nil, userInfo: ["data":[dataArray]])

观察者将会像:

NSNotificationCenter.defaultCenter().
                     addObserver(self, #selector( shouldReload(_:)),
                     name:"newDataNotif", object: nil)

方法如:

func shouldReload(notification:NSNotification) {
  println(notification.userInfo)
}

最后在你的deinit中你应该删除观察者:

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

答案 1 :(得分:4)

我认为做你想做的最简单的方法就是使用委托。

protocol UpdateDelegate {
    func didUpdate(sender: Updates)
}

因此,在您要更新表视图的更新类中,您将调用委托didUpdate函数。 (您必须在开始更新之前设置委托才能调用该方法。)weak关键字很重要,如果不存在,那么这两个类都不会GC,这将导致内存泄漏

class Updates {
   weak var delegate: UpdateDelegate?

   ...

    //Indicates progress finished
    self.delegate.didUpdate(self)

在tableView类中,您可以通过将UpdateDelegate添加到类的顶部来订阅该委托

class ConnectTableVC: UITableViewController, UpdateDelegate {
    ...

    let updates = Updates()
    updates.delegate = self

    ...
    func didUpdate(sender: updates) {
       dispatch_async(dispatch_get_main_queue()) {
          self.tableView.reloadData()
       }
    }
 }

我建议不要使用NSNotificationCenter,最大的原因是任何地方的任何人都可以收听通知(在您的情况下可能不太可能,但仍然值得注意)。

答案 2 :(得分:3)

对于Swift 3

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "newDataNotificationForItemEdit"), object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(self.shouldReload), name: NSNotification.Name(rawValue: "newDataNotificationForItemEdit"), object: nil)

func shouldReload() {
    self.tableView.reloadData()
}

答案 3 :(得分:1)

有很多方法可以做到这一点。最标准的方法是使用委托。委托是iOS中非常常见的模式,您将它与UITableViewDataSource一起使用。您的视图控制器是UITableView的委托,这意味着它符合UITableViewDataSource协议。所以你应该做的是为你的Updates类创建一个协议,如下所示:

protocol UpdatesDelegate {
    func didFinishUpdates(finished: Bool)
}

您的Updates类将具有符合此协议的委托属性:

class Updates {
    var delegate: UpdatesDelegate?

然后将此行放在//indicates progress finished评论为:

的位置
self.delegate?.didFinishUpdates(finished: true)

您的ConnectTableViewController符合协议并从那里重新加载表格视图:

extension ConnectTableViewController: UpdatesDelegate {
    func didFinishUpdates(finished: Bool) {
        guard finished else {
            // Handle the unfinished state
            return 
        }
        self.tableView.reloadData()
    }
}

如果您创建了Updates类的实例,请务必将委托属性设置为ConnectTableViewController

P.S。您的类需要以大写字母开头。我已编辑了您的问题以反映这一点。