繁体   English   中英

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

[英]How to access and refresh a UITableView from another class in Swift

我有一个标签栏应用程序和一个选项卡,其视图控制器由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的//Indicates progress finished

class connectTableVC: UITableViewController {
    ...
}

您可以使用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]?类型的数据[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)
}

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

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,最大的原因是任何地方的任何人都可以收听通知(在您的情况下可能不太可能,但仍然值得注意)。

对于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()
}

有很多方法可以做到这一点。 最标准的方法是使用委托。 委托是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类的实例,请务必将delegate属性设置为ConnectTableViewController

PS你的课程需要以大写字母开头。 我已编辑了您的问题以反映这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM