Kamel
Kamel

Reputation: 41

tableview doesn't refresh deleted data

My table view does not refresh. it keep the old values of deleted data and can show new added values. it only refresh(remove deleted values) when i close the app and open it again.

here is my code

private func observeChannels() {
let userEmail = Auth.auth().currentUser?.email
channelRefHandle = channelRef.observe(.childChanged, with: { (snapshot) -> Void in
  let channelData = snapshot.value as! Dictionary<String, AnyObject>
    let id = snapshot.key
    let groupimage = channelData["groupImage"] as? String!
    let descc = channelData["desc"] as? String!
    let groupCountvar = channelData["Members"]?.count
    let groupTasksVar = channelData["Tasks"]?.count

   if let name = channelData["name"] as! String!, name.characters.count > 0 {
    //members snapshot
    if let childSnapshot = snapshot.childSnapshot(forPath: "Members") as? DataSnapshot{
        if let membersDictionary = childSnapshot.value as? [String:AnyObject] , membersDictionary.count > 0{
            for membersDictionary in membersDictionary {
                if userEmail == membersDictionary.value as? String {
                    self.groups.append(Group(id: id,name: name, createdBy: (userEmail)!, desc: (descc)!, groupImage: (groupimage)!, groupCount: ("\(groupCountvar!)") , groupTasksCount: ("\(groupCountvar!)")))
                    print(membersDictionary.value)

                }
      }
    }

        self.tableView.reloadData()
    }}else {
    print("Error!")
    self.tableView.reloadData()
  }
})}

datasource / delegate

override func numberOfSections(in tableView: UITableView) -> Int {
return 2 }

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let currentSection: Section = Section(rawValue: section) {
  switch currentSection {
  case .createNewChannelSection:
    return 0
  case .currentChannelsSection:
    return groups.count
  }
} else {
  return 0 }
 }

  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 75.0 }

 //tableView
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "ExistingChannel", for: indexPath) as! GroupTableViewCell
if (indexPath as NSIndexPath).section == Section.currentChannelsSection.rawValue {
        cell.goupName?.text = groups[(indexPath as NSIndexPath).row].name
        cell.groupDesc?.text = groups[(indexPath as NSIndexPath).row].desc
        cell.groupimg?.image = UIImage(named: groups[(indexPath as NSIndexPath).row].groupImage)
        cell.numbMembLbl?.text = groups[(indexPath as NSIndexPath).row].groupCount
    cell.taskNumbLbl?.text = groups[(indexPath as NSIndexPath).row].groupTasksCount

}


return cell }

// MARK: UITableViewDelegate

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if (indexPath as NSIndexPath).section == Section.currentChannelsSection.rawValue {
  let channel = groups[(indexPath as NSIndexPath).row]
  self.performSegue(withIdentifier: "ShowChannel", sender: channel)
} }

this is my table view i dont know why the deleted/removed doesn't observe.

Upvotes: 0

Views: 199

Answers (3)

Yash Bedi
Yash Bedi

Reputation: 1355

you need this :

func tableView(_ tableView: UITableView, commit editingStyle: 
 UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
  if editingStyle == .delete {
  print("Deleted")
  self.yourArrayName.remove(at: indexPath.row)
  self.tableView.deleteRows(at: [indexPath], with: .automatic)
 }
}

It'll do the job.

Upvotes: 0

Jay
Jay

Reputation: 35648

You are observing the node for .childChanged events only.

That means the code in the closure will only fire if a child is changed.

From the documentation

FIRDataEventTypeChildChanged - Listen for changes to the items in a list. This event is triggered any time a child node is modified. This includes any modifications to descendants of the child node. The snapshot passed to the event listener contains the updated data for the child.

So that means the code in your closure will only be called when a child is changed, and will not be called when a child is added or deleted.

You need to add additional observers for .childAdded events and .childRemoved events to handle those cases. When you receive a childAdded event, add that snapshot data to your array and likewise when you receive a childRemoved event, remove it from the array.

Remember to reload your table view in all cases so the UI updates with the fresh data.

I personally would change this line to make it more readable

for membersDictionary in membersDictionary {

to

for member in membersDictionary {

but that's just a style thing.

Upvotes: 1

Faysal Ahmed
Faysal Ahmed

Reputation: 7669

Try using this for reloading tableView

DispatchQueue.main.async {
    self.tableView.reloadData()
}

This will help.

Upvotes: 0

Related Questions