2
votes

Comment mettre à jour la ligne tableview après l'action de balayage

J'utilise des actions de balayage dans ma vue de table. Je souhaite ajouter et supprimer de petites icônes sur la ligne une fois l'action de balayage terminée. J'utilise un thread asynchrone pour ce faire, mais cela ne donne pas un résultat lisse comme je le voulais. Mon code est donné ci-dessous, toute aide sera appréciée.

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let groceryAction = groceryToggleAction(forRowAtIndexPath: indexPath)
    let config = UISwipeActionsConfiguration(actions: [groceryAction])
    return config
}

func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let consumeAction = consumeToggleAction(forRowAtIndexPath: indexPath)
    let config = UISwipeActionsConfiguration(actions: [consumeAction])
    return config
}

// MARK: Custom Methods
func groceryToggleAction(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
    let food = foods[indexPath.item]
    let action = UIContextualAction(style: .normal, title: "actionTitle") { (action, view, completionHandler) in

        let food = self.foods[indexPath.item]

        food.isAddedToGrocery = !food.isAddedToGrocery
        self.persistenceManager.saveContext()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
            self.homeTableView.reloadRows(at: [indexPath], with: .none)
        }
        completionHandler(true)
    }
    action.image = #imageLiteral(resourceName: "shoppingCart") // Ä°yi bir liste ikonu bul...
    action.backgroundColor = food.isAddedToGrocery ? UIColor.Palette.alizarin : UIColor.Palette.turquoise
    action.title = food.isAddedToGrocery ? "Remove" : "Add"
    return action
}

func consumeToggleAction(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
    let food = foods[indexPath.item]

    let action = UIContextualAction(style: .normal, title: "actionTitle") { (action, view, completionHandler) in

        food.isConsumed = !food.isConsumed
        self.persistenceManager.saveContext()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
            self.homeTableView.reloadRows(at: [indexPath], with: .none)
        }
        completionHandler(true)

    }
    action.image = #imageLiteral(resourceName: "pacman")
    action.title = food.isConsumed ? "Remove": "Consumed!"
    action.backgroundColor = food.isConsumed ? UIColor.Palette.alizarin : UIColor.Palette.turquoise
    return action
}


0 commentaires

3 Réponses :


0
votes
    DispatchQueue.main.async
    {
        self.tableView.reloadData()
    }
should be just enough.In your code, you force the app to execute at a specific time. If your data is dynamic, such as remote images, they could delay the main loop more than 0.4 seconds and thus cause an even more jerky update and movement.

3 commentaires

Désolé. Mais je dois définir l'icône une fois l'animation de l'action de balayage terminée (une fois le bouton complètement glissé de l'écran). C'est la raison pour laquelle j'ai utilisé un délai de 0,4 seconde. En attendant, mon application est une application hors ligne complète (pour l'instant ...) merci pour la réponse ...


Pourriez-vous placer la fonction «DispatchQueue.main.async» dans le gestionnaire d'achèvement, à la place?


J'ai préparé ci-dessous la fonction donnée et l'ai placée dans complationHandler (self. UpdateRow ()) . Mais le comportement est toujours le même. La ligne se met à jour immédiatement après avoir appuyé sur le bouton de balayage. func updateRow () -> Bool {DispatchQueue.main.async {self.homeTableView.reloadData ()} return true}



0
votes

Vous devez intégrer les lignes de suppression UITableView, cela donnera cette belle animation au lieu de la mise à jour maladroite de la vue de rechargement.

tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)


1 commentaires

Je n'ai jamais pensé à cette solution, cela semble raisonnable :-)



3
votes

Finalement, j'ai compris. J'ai simplement utilisé la fonction ci-dessous du délégué tableview.

    func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {
    print("did end editing")
    guard let indexPath = indexPath else {return}
    tableView.reloadRows(at: [indexPath], with: .none)
}


1 commentaires

J'essaierai ça aussi. Merci pour la suggestion :-)