2015-08-10 1 views
1

J'ai une liste UITableView. J'ai ajouté le code ainsi quand une liste items/ligne est exploité, l'utilisateur peut modifier le contenu des cellules dans une vue modale:Pourquoi la fonction "Tap to Edit" de UITableView est-elle SLOW?

  1. Sur tapotant, le code enregistre le titre/desc de la cellule à vars
  2. lance alors mon point de vue éditeur modal
  3. le principal VC passe l'éditeur VC le titre/desc vars
  4. les valeurs var sont chargées dans les zones de texte afin que l'utilisateur peut les modifier

le problème:

C'est un comportement étrange. Lorsque je teste l'application, le premier fois que j'appuie sur une cellule après l'ouverture de l'application, il y a parfois un délai de 2-3 secondes avant que la vue modale apparaît. Je remarque également que le délai se produit la première fois que j'appuie sur chaque cellule, mais pas sur la seconde. Enfin, parfois après l'ouverture de l'application, il semble ignorer le premier robinet. Est-ce un comportement normal de demande de récupération de données de base?

code chargé sur la principale VC viewDidLoad

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    //Break 

    //Load the list from Core Data 
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
    let managedContext = appDelegate.managedObjectContext! 
    let fetchRequest = NSFetchRequest(entityName:"TodayTask") 
    var error: NSError? 
    let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject] 

    if let results = fetchedResults { 
     todayTaskList = results 
    } else { 
     println("Could not fetch \(error), \(error!.userInfo)") 
    } 

    //Break 

    //This provides a variable height for each row 
    tableView.rowHeight = UITableViewAutomaticDimension 
    tableView.estimatedRowHeight = 80.0 

    //Break 

    //Part of code for cell drag and drop functionality 
    let longpress = UILongPressGestureRecognizer(target: self, action: "longPressGestureRecognized:") 
    tableView.addGestureRecognizer(longpress) 
} 

code exécuté sur le robinet cellulaire

//Action: Performs 'tap on edit' segue 
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    passingEdit = true 
    performSegueWithIdentifier("modalToEditor", sender: nil) 
} 

//Prepares variables to be passed for editing 
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "modalToEditor") && passingEdit == true { 

     //Assign selection to a variable 'currentCell' 
     let indexPath = tableView.indexPathForSelectedRow(); 
     let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! CustomTableViewCell; 

     //Set cell text into variables to pass to editor 
     var cellNameForEdit = currentCell.nameLabel!.text 
     var cellDescForEdit = currentCell.descLabel.text 

     //Pass values to EditorView 
     var editorVC = segue.destinationViewController as! EditorView; 
     editorVC.namePassed = cellNameForEdit 
     editorVC.descPassed = cellDescForEdit 
     editorVC.indexOfTap = indexPath 
    } 
} 
+0

Vous devez appeler 'CoreData' sur le thread 'BackGround'. –

+0

Etes-vous sur iOS8? Je pense que c'est un bug. Voir [cette réponse] (http://stackoverflow.com/a/31073321/3985749) pour un travail autour. Le lien dans le commentaire ci-dessous est également intéressant. – pbasdf

+0

@pbasdf Je suis sur 8.4 - Je vais donner à cette solution de contournement un coup de feu. Merci beaucoup –

Répondre

3

fixe! Après avoir reçu quelques commentaires et fait des recherches sur les suggestions, j'ai pu résoudre ce problème lorsque mes touches ne se connectaient pas rapidement au premier clic (mais une double pression obtient une réponse rapide!). Un commentaire était que je devrais appeler CoreData en arrière-plan, si cela fonctionne, alors beaucoup d'opinions que je lis sont fausses. J'ai lu beaucoup de choses qui disaient que les discussions en arrière-plan pourraient causer le problème. Je n'ai pas essayé cela, donc je ne peux pas confirmer si c'est juste ou faux. Au lieu de cela, le commentaire de @pdasdf m'a mis sur la bonne voie. Si vous créez une table qui segues lorsqu'une cellule est prélevée, vous faites probablement si dans le code qui ressemble à ceci:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    performSegueWithIdentifier("modalToEditor", sender: nil) 

} 

C'est ce que mon code ressemblait. J'avais quelques autres choses à dire à mon PreparForSegue sur ce qui était codé, mais au-dessus est la partie importante. Tout ce que je faisais était de changer cela en:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    dispatch_async(dispatch_get_main_queue()) {() -> Void in 
     self.performSegueWithIdentifier("modalToAllocEditor", sender: nil) 
    } 
} 

Je n'avais jamais utilisé la répartition avant. Cependant, il est conforme à mes lectures qu'il y a une sorte de problème de mise en file d'attente derrière les retards de communication entre cellules ... alors je suppose que cela remédie à tout problème de file d'attente spécifique.

Side note:

Si ce qui précède fixe tous vos problèmes, arrêtez de lire! Ce n'est probablement pas pertinent pour tout le monde.

Si votre didSelectRowAtIndexPath est comme le mien, vous avez en fait un peu plus de code que ci-dessus.J'avais un appel variable 'passingEdit' qui serait mis à jour quand une cellule était tapée et il indiquerait à prepareForSegue si les données doivent être passées.

Dans la nouvelle méthode, si je définissais cette variable dans les parenthèses dispatch {}, elle ne s'exécuterait pas. Donc, si vous avez besoin de faire d'autres choses, assurez-vous que vous le faites dans la fonction tableView, mais en dehors de la fonction d'expédition:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    dispatch_async(dispatch_get_main_queue()) {() -> Void in 
     self.performSegueWithIdentifier("modalToAllocEditor", sender: nil) 
    } 
    passingEdit = true 
} 

Bonne chance.