iOS - 如何在单个视图控制器中插入新的待办事项?

时间:2017-04-16 09:17:19

标签: swift3

当我按下添加按钮时,我想添加一个新的待办事项,但我不想切换到另一个页面。

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

有人建议我将单元数据保存到Model,但我不知道如何写这个。

谁能帮帮我?

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
}
}

1 个答案:

答案 0 :(得分:0)

好的如果我的理解是正确的,如果他们在您的核心数据中创建一个新条目,则需要添加一个新行。因此,在您的视图中,您会看到您正在进行提取。我认为你需要的是:

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")
    }
}
}

首先我很抱歉,但我刚才写的是stackOverflow。所以你正在做的是使用获取结果控制器而不是传统搜索。您还需要拥有排序描述符,您可以尝试获取结果并将其转换为项目或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的名称更改为&#34; tableView&#34;以外的其他名称。只是为了清楚。

中间的方法使用开关。我的例子是错过了&#34; Move&#34;和&#34;删除&#34;选项,因为我没有在我的项目中需要它们,但您可以将它们添加到switch语句中。

插入正在检查newIndexPath以查看是否存在。如果是这样,那么我们添加newIndexPath所需的行数量的数组。

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

我希望这就是你要找的东西。祝好运!如果你需要,我会尝试并提供更多帮助,但这应该让你开始。