简体   繁体   中英

How to refresh tableview after deleting row in swift?

I have three view controllers.

VC1 and VC3 are UITableViewControllers subclasses, VC2 is UIViewController subclass.

VC1 pass some data to VC2. VC2 save data using userdefaults to an array. Then VC2 pass this data using segue to VC3. VC3 shows data in a table view.

I've added a swipe gesture to delete data from table view at VC3. And it works good. But when I go back (VC3 -> VC2) and again come back to (VC2 -> VC3) deleted row still exists with data. But when i go to VC3 -> VC2 -> VC1 and back again VC1 -> VC2 -> VC3 I found that deleted row actually deleted. I want when VC3 > VC2 then VC2 > VC3 there will be no deleted data exist.

All view controllers are in UINavigationController stack. Code is written with Swift 2.

Why dont you write a function for all views with corresponding tables.

it's like

import Foundation import UIKit

class DeleteRows{
    class func removeRowAtIndexPath(indexPathRow: Int, indexPathSec: Int, table: UITableView) -> UITableView{
arrayOfSomethin.removeAtIndex(indexPathRow)
    let index = NSIndexPath(forItem: indexPathRow, inSection: indexPathSec)
    table.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Left)

    return table
}
}

You can call them by DeleteRows.removeRowAtIndexPath(indexPathRow: 0, indexPathSec: 0,table:Yourtable).delegate = self

You need to delete the data from the datasource and update the tableview with tableview.reloadData()

EDIT!!

When you navigate back to VC2(VC3-> VC2) you should bring a reference to what data you deleted so it can be deleted from the dataSource(array, nsuserdefaults). That way when you want to navigate from VC2 -> VC3 you will bring a fresh array from NSUserDefaults and then reload the tableview with that new data.

But I recommend you to make this simpler for you. It seems like you are making trouble for yourself. If you want to access an array with data from multiple viewControllers you should make a new file with a class that holds the array. Take a look at this sudo code:

"dataSource.swift"


Class DataSource{
    var arrayWithData = [String]()


    init(){
         let userDefault = NSUserDefaults.standardUserDefaults()
         self.arrayWithData = userDefaults.arrayForKey("arrayData")
    }

     func deleteData(){
         //Edit the self.arrayWithData and then run this method
         let userDefault = NSUserDefaults.standardUserDefaults()
         userDefault.updateValue(self.arrayWithData, forKey "arrayData")
      }

}

Best solution One of the solutions in your case might be to use a Notification pattern.

Send notification from your VC3 class:

NSNotificationCenter.defaultCenter().postNotificationName("ObjectDeleted", object: ["object" : object])

In your VC1 & VC2 you have to subscribe for delete events (somewhere at viewDidLoad() )

NSNotificationCenter.defaultCenter().addObserver(self,
                                                 selector: #selector(VC1.objectDeleted(_:)),
                                                 name: "ObjectDeleted",
                                                 object: nil)

And you can process it like:

func objectDeleted(notification: NSNotification) {

    guard let object = userInfo["object"] as? YourObjectClass else { return }
    guard let index = dataArray.indexOf(object) else { return }

    dataArray.removeAtIndex(index)
    tableView.deleteRowsAtIndexPaths([NSIndexPath.init(forRow: index, inSection: 0)], withRowAnimation: .Automatic)
}

For VC2 you can update your NSUserDefaults container as well in the function above.

Using iOS 8 or earlier you need to unregister for this notification before deallocating the observer object (VC1 or VC2 in your case). If you forget you are at risk of a crash when the notification center sends the next notification to an object that no longer exists. So don'n forget to add a deinit call :

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

You will need to update the data after deletion.

In viewDidLoad() or at the end of delete method, add:

tableview.reloadData()

This should help update the view(s).

To store/persist data, use UserDefaults.

func storeData(name: String) {

    let defaults = UserDefaults.standard
    defaults.set(name, forKey: "Name")
    defaults.synchronize() // Save Data

}

func getData() -> String {

    if let name = UserDefaults.standard.object(forKey: "Name") {
        return name as! String
    } else {
        return "" // error in retrieving data (ex: name not found)
    }

}

First thing is to delete the data from your data source that populates your tableView. Most likely you have an array of some class/struct type such as let usersArray = [Users]()
Then you need to delete the row from the tableView.
Note!!! If you use reload tableView.reloadRows(at: [indexPath], with: .automatic) the app will crash. This methods acts as if you are inserting a row, but your data source is telling there is no data for that specific index, hence the reason why you are should use table.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Left)

//remove users from dataSource
  usersArray.remove(at:indexPath.row)
 //delete the row of the tableView
  table.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Left)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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