我是swift的初学者,我试图建立一个带有tableView的购物清单应用程序。近乎工作,除了: 重新排序行,退出应用程序并返回时,新行顺序未保存。 有什么想法吗?
这是重要的部分:
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObject = shoppingList[sourceIndexPath.row]
shoppingList.remove(at: sourceIndexPath.row)
shoppingList.insert(movedObject, at: destinationIndexPath.row)
}
但是不会起作用.....
以下是整个代码:
import UIKit
import CoreData
var shoppingList: [NSManagedObject] = [ ]
class ShoppingList_1: UIViewController, UITableViewDelegate,UITableViewDataSource {
//Anzahl Spalten -->
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
//**************************
//Zeilen: dynamisch; abhängig von Anzahl items in Liste -->
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return shoppingList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = shoppingList[indexPath.row]
let cell = Cell.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
// <-- Prototype Cell für Ausschnitt/Sicht des Bildschirms
cell.textLabel?.text = item.value(forKeyPath: "itemName") as? String
cell.detailTextLabel?.text = "\(indexPath.row)"
return cell
}
//免费使用 func tableView(_ tableView:UITableView,canMoveRowAt indexPath:IndexPath) - &gt;布尔{ 返回true }
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
print("Daten geladen!\n")
let movedObject = shoppingList[sourceIndexPath.row]
shoppingList.remove(at: sourceIndexPath.row)
shoppingList.insert(movedObject, at: destinationIndexPath.row)
NSLog("%@", "\(sourceIndexPath.row) => \(destinationIndexPath.row) \(shoppingList)")
// To check for correctness enable: self.tableView.reloadData()
}
//*****************************************************************************************************
//Durch wischen entfernen -->
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete
{
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(shoppingList[indexPath.row])
do {
try managedContext.save()
shoppingList.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
} catch let err as NSError {
print("12345", err)
}
}
}
@IBOutlet weak var AddButton: UIButton!
@IBOutlet weak var AddItem: UITextField!
@IBOutlet weak var Cell: UITableView!
@IBAction func EditTopRightButton(_ sender: UIBarButtonItem) {
self.Cell.isEditing = !self.Cell.isEditing
sender.title = (self.Cell.isEditing) ? "Done" : "Edit"
}
//Button Action
@IBAction func AddButton2_Test(_ sender: Any) {
print("My test")
let a:Float = 2
let b:Float = 3
let Ergebnis:Float = a+b
print(Ergebnis)
if (AddItem.text != "")
{
self.save(AddItem.text!)
}
Cell.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Item")
do {
shoppingList = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
func save(_ itemName: String){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Item", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(itemName, forKey: "itemName")
do {
try managedContext.save()
shoppingList.append(item)
} catch let err as NSError {
print("Failed to save item",err)
}
}
//*****************************************************************************************************
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Cell.delegate = self
Cell.dataSource = self
AddItem.delegate = self
}
//HINZU-->
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//*****************************************************************************************************
// extensions -->
extension ShoppingList_1 : UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
AddItem.resignFirstResponder()
return true
}
}
//***************************************
答案 0 :(得分:0)
当前工作
在您的代码中,Table视图加载了来自viewWillAppear
的Coredata的数据。在TableView中更改顺序时,不会更新插入到核心数据的数据。
所以即使你改变了Array中单元格和corder的顺序。每次viewWillAppear
调用时,都会从没有订单的Coredata中再次获取数据。
ViewWillAppear
都会调用。如果您从任何其他呈现的视图ViewWillAppear
将回拨此视图。
<强> Sollution 强>
您可以在表格中创建一个新属性,描述Coredata Entity&amp;在获取后按此顺序对项目进行排序。 请参阅此答案以了解如何使用核心数据设置显示顺序 https://stackoverflow.com/a/31907857/4845644
或者如果您的要求只是为了保持订单到ViewController实例,则需要将核心数据提取代码从viewWillAppear
更改为viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
Cell.delegate = self
Cell.dataSource = self
AddItem.delegate = self
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Item")
do {
shoppingList = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}