1

I have a table view where two cells have UITextView into which the user can enter long data. Following some answers here in Stackoverflow, I implemented a protocol/delegate to detect when the user has finished entering the data which then will be saved in a global dictionary:

class DetailsNewTaskViewController: UITableViewController, TextViewCellDelegate {

var cellData:[String:String] = [:]

 func controllerView(controller: UITableViewCell, textViewDidEndEditing: String, atIndex:Int) {

        switch(atIndex) {
            case 0:
                self.cellData["titolo"] = (controller as! LittleTextCell).textView.text
                break
            case 1:
                self.cellData["oggetto"] = (controller as! BigTextCell).textView.text
                break
            default:
                break
        }
 }

and this is the relative custom cell class:

class LittleTextCell: UITableViewCell, UITextViewDelegate {
  @IBOutlet weak var label : UILabel!
  @IBOutlet weak var textView : UITextView!
  var delegate:TextViewCellDelegate?
  var rowIndex:Int?

  func textViewDidEndEditing(textView: UITextView) {
    delegate?.controllerView(self, textViewDidEndEditing: textView.text, atIndex: rowIndex!)
  }
}

where the delegate for textView is the class itself.

And this is a screenshot of the application: enter image description here

The "problem" is that only AFTER the user taps another cell/field then the text is stored in the global dictionary. What about if the user taps "Fine" button (to save data) without having touched another field after he's finished entering the text? That a fatal nil error is raised. So I would like to know if there is a way to detect that the user has stopped typing in even if he's still inside that cell so that the content is always stored. Is it possible? Is there a particular method to implement?

UPDATE: the function associated to "Fine" button:

func saveTask(sender:UIButton!) {

    self.dateFormatter.dateFormat = "yyyy-MM-dd"

    var taskToSave = Task(id: -1,
                          titolo: self.cellData["titolo"]!,
                          oggetto: self.cellData["oggetto"]!,
                          check_mail: self.cellData["check_mail"]!.toBool()!,
                          id_progetto: self.projects[self.cellData["progetto_nome"]!]!.id,
                          progetto_nome: nil,
                          assegnato_a: nil,
                          id_assegnato_a: self.users[self.cellData["assegnato_a"]!]!.id,
                          richiesto_da: nil,
                          id_richiesto_da: self.users[self.cellData["richiesto_da"]!]!.id,
                          priorita: self.cellData["priorita"]!,
                          termine_consegna: self.dateFormatter.dateFromString(self.cellData["termine_consegna"]!)!,
                          stato: self.cellData["stato"]!)

      self.taskService.addTaskService(taskToSave) {
        (response: String) in

        if ((response.rangeOfString("Could not connect to the server.")) != nil) {
            dispatch_async(dispatch_get_main_queue()) {
                self.alertView.title = "Operazione fallita!"
                self.alertView.message = "Impossibile connettersi al server. \n Riprovare."
                self.alertView.delegate = self
                self.alertView.addButtonWithTitle("OK")
                self.alertView.show()
            }
            println(response)
        }

        else {
            if ((response.rangeOfString("status code: 200")) != nil) {
                dispatch_async(dispatch_get_main_queue()) {
                    self.alertView.title = "Operazione eseguita!"
                    self.alertView.message = "Task creato correttamente"
                    self.alertView.delegate = self
                    self.alertView.addButtonWithTitle("OK")
                    self.alertView.show()

                    self.navigationController?.popViewControllerAnimated(true)
                }
            }

            else {
                println(response)
            }

        }
    }
}
SagittariusA
  • 5,289
  • 15
  • 73
  • 127

2 Answers2

1

just use this line on the top in the method fine in your controller

self._tableView.superview?.endEditing(true);

I was facing the same problem , my textfields in cell and i want to check all the fields in controller.When i get my data so last data is not up to date because after last data, i click on the button not on the text field. So i found the solution. I wrote this line in my method (in your case, this line should be in fine method) before getting my dictionary and after that i had updated data. Thanks

Umair_UAS
  • 113
  • 1
  • 10
1

define global selectedIndexPath

var selectedIndexPath:Int = 0

set it to selected indexPath

 func controllerView(controller: UITableViewCell, textViewDidEndEditing: String, atIndex:Int) {
        selectedIndexPath = indexPath
        switch(atIndex) {
            case 0:
                self.cellData["titolo"] = (controller as! LittleTextCell).textView.text
                break
            case 1:
                self.cellData["oggetto"] = (controller as! BigTextCell).textView.text
                break
            default:
                break
        }
 }

In saveTask function get cell with cellForRowAtIndexPath

 func saveTask(sender:UIButton!) {

        let cell = tableView.cellForRowAtIndexPath(selectedIndexPath)
        self.cellData["titolo"] = cell.LittleTextCell.textView.text
        self.cellData["oggetto"] = cell.BigTextCell.textView.text
  }
Özgür Ersil
  • 6,909
  • 3
  • 19
  • 29