如何从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 { ... }
我认为最简单的做法是使用委托。
protocol UpdateDelegate { func didUpdate(sender: Updates) }
因此,在您的更新类中,要刷新表视图的位置,您可以调用委托didUpdate函数。 (你必须在开始调用方法的更新之前设置委托。)弱关键字是重要的,如果它不在那里,那么这两个类都不会GC'd,这将导致内存泄漏。
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() } } }
我build议不要使用NSNotificationCenter,最大的原因是任何人都可以听取通知(这可能不太可能在你的情况下,但它仍然值得注意)。
您可以使用protocol
或NSNotificationCenter
NSNotificationCenter
示例:
在下载数据的UIViewController
中,可以在完成下载数据后发布通知,并告诉其他对象有新数据:
NSNotificationCenter.defaultCenter(). postNotificationName("newDataNotif", object: nil)
而任何其他想听这个通知的对象都应该注册以观察(在你的情况下是UITableViewController
):
NSNotificationCenter.defaultCenter(). addObserver(self, #selector(shouldReload), name:"newDataNotif", object: nil)
然后在接收通知时需要实现要调用的方法:
func shouldReload() { self.tableView.reloadData() }
请注意,通知也可以发送types为[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) }
有很多方法可以做到这一点。 最标准的方法是使用委托。 委托是iOS中非常常见的模式,您正在使用它与UITableViewDataSource。 您的视图控制器是UITableView的委托,意味着它符合UITableViewDataSource协议。 所以你应该做的是为你的Updates
类创build一个协议,像这样:
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() } }
在创buildUpdates
类的实例的时候,一定要把delegate属性设置为你的ConnectTableViewController
。
PS您的课程需要以大写字母开头。 我已经编辑你的问题来反映这一点。
对于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() }
- 如何禁用UITextview选择文本,复制/粘贴UIMenuController但仍然有超链接工作
- 如何更改NavigatorIOS的标题而不更改React Native中的路线
- 在视图控制器转换时获取子视图的最终框架
- Autolayout的UIViewPropertyAnimator问题
- 什么是从UITableView“拉刷新”的最佳途径?
- NSManagedObject的自定义初始值设定项
- 现在,testflight库和Xcode 5中没有任何更改说:“找不到-lTestFlight的ld:库”
- CTLineGetTypographicBounds的问题
- 如何在故事板中使用search结果控制器使用原型单元格