简体   繁体   English

快速删除行后如何刷新TableView?

[英]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和VC3是UITableViewControllers子类,VC2是UIViewController子类。

VC1 pass some data to VC2. VC1将一些数据传递给VC2。 VC2 save data using userdefaults to an array. VC2使用userdefaults将数据保存到数组。 Then VC2 pass this data using segue to VC3. 然后,VC2使用segue将此数据传递给VC3。 VC3 shows data in a table view. VC3以表格视图显示数据。

I've added a swipe gesture to delete data from table view at VC3. 我添加了滑动手势以从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. 但是当我返回(VC3-> VC2)并再次返回(VC2-> VC3)时,已删除的行仍然存在数据。 But when i go to VC3 -> VC2 -> VC1 and back again VC1 -> VC2 -> VC3 I found that deleted row actually deleted. 但是当我转到VC3-> VC2-> VC1并再次返回VC1-> VC2-> VC3时,我发现删除的行实际上已删除。 I want when VC3 > VC2 then VC2 > VC3 there will be no deleted data exist. 我想当VC3> VC2然后VC2> VC3时将不存在已删除的数据。

All view controllers are in UINavigationController stack. 所有视图控制器都在UINavigationController堆栈中。 Code is written with Swift 2. 代码是用Swift 2编写的。

Why dont you write a function for all views with corresponding tables. 为什么不为具有相应表的所有视图编写函数。

it's like 就像是

import Foundation import UIKit 导入Foundation导入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 您可以通过DeleteRows.removeRowAtIndexPath(indexPathRow:0,indexPathSec:0,table:Yourtable)来调用它们。

You need to delete the data from the datasource and update the tableview with tableview.reloadData() 您需要从数据源中删除数据,并使用tableview.reloadData()更新tableview

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). 当您导航回VC2(VC3-> VC2)时,应该引用删除的数据,以便可以从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. 这样,当您要从VC2-> VC3导航时,您将从NSUserDefaults中获取一个新的数组,然后使用该新数据重新加载tableview。

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. 如果要使用来自多个viewController的数据访问数组,则应使用包含该数组的类制作一个新文件。 Take a look at this sudo code: 看一下下面的sudo代码:

"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: 从您的VC3类发送通知:

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

In your VC1 & VC2 you have to subscribe for delete events (somewhere at viewDidLoad() ) 在VC1和VC2中,您必须订阅删除事件(在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. 对于VC2,您还可以在上面的函数中更新NSUserDefaults容器。

Using iOS 8 or earlier you need to unregister for this notification before deallocating the observer object (VC1 or VC2 in your case). 使用iOS 8或更早版本,您需要先取消注册此通知,然后再释放观察者对象(在您的情况下为VC1或VC2)。 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调用

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

You will need to update the data after deletion. 删除后,您将需要更新数据。

In viewDidLoad() or at the end of delete method, add: 在viewDidLoad()或delete方法的末尾,添加:

tableview.reloadData()

This should help update the view(s). 这应该有助于更新视图。

To store/persist data, use UserDefaults. 要存储/保留数据,请使用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. 第一件事是从填充tableView的数据源中删除数据。 Most likely you have an array of some class/struct type such as let usersArray = [Users]() 您最有可能拥有某些类/结构类型的数组,例如let usersArray = [Users]()
Then you need to delete the row from the tableView. 然后,您需要从tableView中删除该行。
Note!!! 注意!!! If you use reload tableView.reloadRows(at: [indexPath], with: .automatic) the app will crash. 如果您使用reload tableView.reloadRows(at: [indexPath], with: .automatic)则应用程序将崩溃。 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) 此方法的作用就像您要插入一行,但是您的数据源告诉您该特定索引没有数据,因此应使用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)

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

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