Reputation: 1810
I have a UITableViewCell
that I use in several UITableView
's that are in differents UIViewController
's. From my cell, there is an object that I update but I would like to update it also in the array of my controllers. How ?
For example :
UITableViewCell :
class NotificationTableViewCell: UITableViewCell {
@IBOutlet weak var buttonRead: UIButton!
var notification = Notification()
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func clickButtonRead(_ sender: Any) {
self.notification.isRead = true
}
}
UIViewController :
class NotificationsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITabBarControllerDelegate {
@IBOutlet weak var tableView: UITableView!
/* List notifications */
var listNotifications = [Notification]()
override func viewDidLoad() {
super.viewDidLoad()
//View cell
let nib = UINib(nibName: "viewNotificationTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "cellNotification")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listNotifications.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cellNotification", for: indexPath) as! NotificationTableViewCell
cell.notification = self.listNotifications[indexPath.row]
return cell
}
}
EDIT :
I can pass the controller and the indexPath to the cell for update the object notification in listNotifications like this : self.controller.listNotifications[indexPath.row] = self.notification
But if i use this cell with more controllers, I must cast the controller from cell to know what controller is it.
I am looking for a way to update the object without having to cast the controller.
Upvotes: 1
Views: 185
Reputation: 1383
You can achieve this by using protocol make a protocol in your tableview Cell Class
protocol NotificationDelegate{
func didReadNotification(notification:Notification , index:Int)
}
class NotificationTableViewCell: UITableViewCell {
@IBOutlet weak var buttonRead: UIButton!
// and make this optional don't initialize it
var notification:Notification?
var delegate:NotificationDelegate?
var indexOfNotification:Int?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func clickButtonRead(_ sender: Any) {
self.notification?.isRead = true
self.delegate?.didReadNotification(notification:self.notification! , index:indexOfNotification!)
}
}
and add NotificationDelegate in you ViewController
class NotificationsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITabBarControllerDelegate , NotificationDelegate {
@IBOutlet weak var tableView: UITableView!
/* List notifications */
var listNotifications = [Notification]()
override func viewDidLoad() {
super.viewDidLoad()
//View cell
let nib = UINib(nibName: "viewNotificationTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "cellNotification")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listNotifications.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cellNotification", for: indexPath) as! NotificationTableViewCell
cell.notification = self.listNotifications[indexPath.row]
cell.delegate = self
cell.indexOfNotification = indexPath.row
return cell
}
// This Delegte method will be called whenever user read the notification
func didReadNotification(notification:Notification , index:Int){
// do what ever you want here is your index and notification..
let notification = listNotifications[index] // this is your notification in listNotifications
}
}
Upvotes: 1
Reputation: 374
The ideal way to do it is you create a NotificationTableViewCellDelegate and set the delegate to view controller. In your method clickButtonRead call the delegate method and update the object in the view controller.
protocol NotificationTableViewCellDelegate {
func enableReadForNotification(notification: Notification)
}
class NotificationTableViewCell: UITableViewCell {
@IBOutlet weak var buttonRead: UIButton!
var notification = Notification()
weak var delegate: NotificationTableViewCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func clickButtonRead(_ sender: Any) {
self.notification.isRead = true
if let delegate = self.delegate {
delegate.enableReadForNotification(self.notification)
}
}
}
Hope this helps!
Upvotes: 2