代码之家  ›  专栏  ›  技术社区  ›  ashwin nath

如何持久化tableview行?

  •  0
  • ashwin nath  · 技术社区  · 7 年前

    我正在创建一个ios应用程序,它每天都会向我显示一组特定于用户的任务,我可以点击删除这些任务以显示其完成情况。我将任务保存在核心数据中,只需单击即可删除tableview行。我不删除coredata中用户定义的数据,需要每天重新加载。如果在新的一天打开应用程序,我使用newDay()函数来决定从coredata加载数据。我该怎么做才能记住当天哪些任务都完成了?我是否需要创建另一个enity来记住哪些任务都已完成,还是有更简单的方法?

    var tasks: [NSManagedObject] = []
    let defaults = UserDefaults.standard
    var calender = Calendar.current
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        title = "DailyTasker"
        navigationItem.leftBarButtonItem = editButtonItem
    
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        let checkDate = newDay()
        if checkDate{
    
        //1
        guard let appDelegate =
            UIApplication.shared.delegate as? AppDelegate else {
                return
        }
    
        let managedContext =
            appDelegate.persistentContainer.viewContext
    
        //2
        let fetchRequest =
            NSFetchRequest<NSManagedObject>(entityName: "Task")
    
        //3
        do {
            tasks = try managedContext.fetch(fetchRequest)
            defaults.set(Date(), forKey: "LastRun")
        } catch let error as NSError {
            print("Could not fetch. \(error), \(error.userInfo)")
        }
        }
    }
    
    func newDay() -> Bool{
        if let lastRun = defaults.object(forKey: "LastRun") as? Date{
            if !calender.isDateInToday(lastRun){
                return true
            } else {
                return false
            }
        } else {
            return true
        }
    
    }
    
    
    @IBAction func addName(_ sender: UIBarButtonItem) {
        let alert = UIAlertController(title: "New Task",
                                      message: "Add a new task",
                                      preferredStyle: .alert)
    
        let saveAction = UIAlertAction(title: "Save",
                                       style: .default) {
                                        [unowned self] action in
    
                                        guard let textField = alert.textFields?.first,
                                            let nameToSave = textField.text else {
                                                return
                                        }
    
                                        self.save(name: nameToSave)
                                        self.tableView.reloadData()
        }
    
        let cancelAction = UIAlertAction(title: "Cancel",
                                         style: .default)
    
        alert.addTextField()
    
        alert.addAction(saveAction)
        alert.addAction(cancelAction)
    
        present(alert, animated: true)
    }
    
    func save(name: String) {
    
        guard let appDelegate =
            UIApplication.shared.delegate as? AppDelegate else {
                return
        }
    
        // 1
        let managedContext =
            appDelegate.persistentContainer.viewContext
    
        // 2
        let entity =
            NSEntityDescription.entity(forEntityName: "Task",
                                       in: managedContext)!
    
        let task = NSManagedObject(entity: entity,
                                   insertInto: managedContext)
    
        // 3
        task.setValue(name, forKeyPath: "name")
    
        // 4
        do {
            try managedContext.save()
            tasks.append(task)
        } catch let error as NSError {
            print("Could not save. \(error), \(error.userInfo)")
        }
    
    }
    
    // MARK: - Table view data source
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return tasks.count
    }
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let task = tasks[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "TaskerCell", for: indexPath)
        cell.textLabel?.text = task.value(forKeyPath: "name") as? String
    
        return cell
    }       
    
     // Override to support editing the table view.
     override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
     if editingStyle == .delete {
     // Delete the row from the data source
     tasks.remove(at: indexPath.row)
     tableView.deleteRows(at: [indexPath], with: .fade)
     } else if editingStyle == .insert {
    
     }
     }
    
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tasks.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
    }    
    

    }

    2 回复  |  直到 7 年前
        1
  •  0
  •   Joakim Danielson    7 年前

    您可以将日期属性添加到任务中并将其命名 lastDone 例如。然后将其设置为任务完成时的当前日期时间,并在获取任务实例时使用谓词,以便只获取今天未完成的实例。

     task.lastDone = Date()
    

    我不知道你如何定义“今天”,但是 this question 应该可以帮助您创建一个谓词来正确过滤任务,尽管您可能还希望在其中包含任务 上次完成 为空。

        2
  •  0
  •   ashish    7 年前

    我不知道你为什么不能删除数据。是因为规格问题吗。 如果没有,则在coredata中保存任务时,只需使用唯一标识符(id)对其进行分配,然后就可以创建自己的数据堆栈方法来删除特定任务。

    可以为任务示例创建数据模型类或结构

    class TaskData {
      var id: Int!
      var task: String!
    
      init(id: Int, task: String) {
        self.id = id
        self.task = task
      }
    }
    

    将任务作为此数据类保存到coreData中。

    当您当时删除行时,请捕获任务Id并将其从coreDataStack中删除。

    一个好方法是创建一个TaskManager Singelton类来处理所有核心数据方法。