2017-04-16 74 views
0

我想添加一个新的待办事项当我按下添加按钮,但我不想切换到另一个页面。iOS - 如何在单个视图控制器中插入新的待办事项?

按下添加按钮在表格视图中添加一个新行,输入内容并按下完成按钮,它会保存。

有人建议我将细胞数据保存到模型,但我不知道如何写这个。

谁能帮帮我?

import UIKit 
import CoreData 

class ToDoViewController: UIViewController { 

var items: [NSManagedObject] = [] 

@IBOutlet weak var tableView: UITableView! 

@IBAction func addItem(_ sender: UIBarButtonItem) { 


    //***How to write this code*** 


} 

@IBAction func done(_ sender: UIBarButtonItem) { 
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { 
     return 
    } 

    let managedContext = appDelegate.persistentContainer.viewContext 

    let entity = NSEntityDescription.entity(forEntityName: "ToDo", in: managedContext)! 

    let item = NSManagedObject(entity: entity, insertInto: managedContext) 

    //***let list = the current textView's text 
    //how to get the textView's text and assign it to a value.*** 

    item.setValue(list, forKeyPath: "summary") 


    do { 
     try managedContext.save() 

     items.append(item) 

    } catch let error as NSError { 
     print("Could not save.\(error),\(error.userInfo)") 
    } 

} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    tableView.register(UITableViewCell.self,forCellReuseIdentifier: "Cell") 

} 

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: "ToDo") 

    do { 
     items = try managedContext.fetch(fetchRequest) 
    } catch let error as NSError { 
     print("Could not fetch.\(error),\(error.userInfo)") 
    } 
} 


} 

extension ToDoViewController: UITableViewDataSource{ 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return items.count 
} 

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

    let item = items[indexPath.row] 

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 

    let textView = UITextView(frame: CGRect(x: 0, y: 0, width: cell.frame.size.width, height: cell.frame.size.height)) 
    cell.addSubview(textView) 

    textView.text = item.value(forKey: "summary") as? String 

    return cell 
} 
} 
+0

我刚刚做了类似的事情,但它会帮助您在看到您的代码之前给我一个完整的答案。你可以理解你的代码和你想要做的事情,但我们需要看到一些人的帮助。 – CardDeath

+0

我编辑了这篇文章 – wDalian

回答

0

好吧,如果我的理解是正确的,你需要添加一个新行,如果他们创建一个新的条目到你的核心数据。所以在你的viewWillAppear你正在做一个抓取。我想你需要的是:

var fetchResultController : NSFetchedResultsController<YourType>! 

然后使用这个取数据控制器,你要做到以下几点进行读取时:

private func GetToDoEntries(){ 
    if let appDele = UIApplication.shared.deletgate as? AppDelegate{ 
    let givenContext = appDele.persistantContainer.viewContex 
    let entryFetchRequest : NSFetchRequest<YourType> = YourType.fetchRequest() 

    let sortDescriptors = NSSortDescriptor(key: "yourEntrySortKey" , ascending: true) 
    entryFetchRequest.sortDescriptors = [sortDescriptors] 

    fetchResultController = NSFetchedResultsController(fetchRequest: entryFetchRequest, managedObjectContext: givenContext, sectionNameKeyPath: nil, cacheName: nil) 
    fetchResultController.delegate = self 
    do{ 
     //Gets fetched data based on our criteria 
     try fetchResultController.performFetch() 
     if let fetchedEntries = fetchResultController.fetchedObjects{ 
      items = fetchedEntries as? WhateverToCastTo 
     } 
    }catch{ 
     print("Error when trying to find entries") 
    } 
} 
} 

首先,我很抱歉,但我刚刚写了这以下是堆栈溢出。所以你在做什么是使用取数结果控制器而不是传统的搜索。您还需要具有排序描述符,您可以尝试获取结果并将它们转换为项目或NSManagedObject。

现在我们还没有完成。你的脚本需要继承一些行为。在你的类

class ToDoViewController : UIViewController, NSFetchedResultsControllerDelegate 

的顶部,你需要委托,你可以在代码的第一块看,因为我们赋予它。现在我们快到了。你只需要一些方法来为你更新表格,这些方法来自我们继承的委托。

//Allows the fetch controller to update 
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.beginUpdates() 
} 

//Allows new additions to be added to the table 
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch type{ 
    case .insert: 
     if let _newIndexPath = newIndexPath{ 
      tableView.insertRows(at: [_newIndexPath], with: .fade) 
     } 
    case .update: 
     if let index = indexPath{ 
      tableView.reloadRows(at: [index], with: .fade) 
     } 
    default: 
     budgetEntryTable.reloadData() 
    } 

    if let fetchedObjects = controller.fetchedObjects{ 
     items = fetchedObjects as! [NSManagedObject (Or your cast type)] 
     budgetEntryTable.reloadData() 
    } 
} 

//Ends the table adding 
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.endUpdates() 
} 

所以这里有3种方法。第一个和第二个非常自我解释。他们开始并结束你的tableView的更新。为了清楚起见,我还建议您将tableView的名称更改为“tableView”以外的名称。

中间的方法使用开关。我的例子是缺少“移动”和“删除”选项,因为我没有在我的项目中需要它们,但可以将它们添加到switch语句中。

插入检查newIndexPath是否有一个。如果是这样的话,我们添加一个newIndexPath所需的行数的数组。

更新只是检查当前的索引路径,然后重新加载数据在您更新数据模型之前。

我希望这是你正在寻找的。祝你好运!如果你需要它,我会尽力帮助你,但是这会让你开始。

+0

感谢您编写这么多,但....如何编写添加和完成操作?我只是了解从数据库保存和提取数据的基本用法,我还没有使用NSFetchedResultsController 。什么是使用它的意思..我只想通过按下添加按钮来创建一个新的单元格,并将文本保存到数据库中,然后使用viewwillappear方法来获取数据,并将数据显示在屏幕上。 – wDalian

+0

基本上你的视图将出现在哪里你应该使用我提供的NSFetchResultsController信息进行获取。目的是在正确的时间用正确的数据更新你的表格。当我在表格视图中使用重载数据时,例如你无法使用。尝试遵循我的建议。您已经在完成的方法中将条目添加到核心数据中。你能从我写的内容中弄清楚吗?如果没有,我会尽量详细说明,但如果需要的话,您可以阅读NSFetchedResultsController。 – CardDeath

+0

我将尝试更改我的代码,但请允许我首先了解NSFetchResultsController的用法。 – wDalian

相关问题