web-dev-qa-db-fra.com

UITableview fait défiler vers le haut sur Recharger

Je suis confronté à un problème dans mon application - vous pouvez poster et éditer vos endroits préférés. Après avoir posté un article ou édité un article spécifique (UITableViewCell), UITableview est rechargé.

Mon problème est le suivant: la UITableview défile vers le haut après le rechargement. Mais ce n'est pas ce que je veux. Je veux que ma vue reste sur la cellule/vue où j'étais. Mais je ne sais pas comment gérer ça. 

Pourriez-vous m'aider?

14
debbiedowner

La réponse d'Igor est correcte si vous utilisez des cellules redimensionnables de manière dynamique (UITableViewAutomaticDimension).

La voici dans Swift 3:

    private var cellHeights: [IndexPath: CGFloat?] = [:]
    var expandedIndexPaths: [IndexPath] = []

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cellHeights[indexPath] = cell.frame.height
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if let height = cellHeights[indexPath] {
            return height ?? UITableViewAutomaticDimension
        }
        return UITableViewAutomaticDimension
    }


    func expandCell(cell: UITableViewCell) {
      if let indexPath = tableView.indexPath(for: cell) {
        if !expandedIndexPaths.contains(indexPath) {
            expandedIndexPaths.append(indexPath)
            cellHeights[indexPath] = nil
            tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
            //tableView.scrollToRow(at: indexPath, at: .top, animated: true)
        }
      }
    }
22
Kurt J

Pour empêcher le défilement vers le haut, vous devez enregistrer les hauteurs de cellules lors de leur chargement et donner la valeur exacte dans tableView:estimatedHeightForRowAtIndexPath:

// declare cellHeightsDictionary
NSMutableDictionary *cellHeightsDictionary;

// initialize it in ViewDidLoad or other place
cellHeightsDictionary = @{}.mutableCopy;

// save height
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cellHeightsDictionary setObject:@(cell.frame.size.height) forKey:indexPath];
}

// give exact height value
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];
    if (height) return height.doubleValue;
    return UITableViewAutomaticDimension;
}
15
Igor

La méthode reloadData() de UITableView est explicitement un rechargement forcé de la tableView entière. Cela fonctionne bien, mais la plupart du temps, c’est discordant et une mauvaise expérience utilisateur si vous envisagez de le faire avec une table vue par l’utilisateur.

Au lieu de cela, jetez un coup d'œil à reloadRowsAtIndexPaths(_:withRowAnimation:) et reloadSections(_:withRowAnimation:)dans la documentation .

11
SpacyRicochet

Allez juste pour ces lignes si vous voulez une solution facile

    let contentOffset = tableView.contentOffset
    tableView.reloadData()
    tableView.setContentOffset(contentOffset, animated: false)
4
zeiteisen

Dans Swift 3.1

DispatchQueue.main.async(execute: {

    self.TableView.reloadData()
    self.TableView.contentOffset = .zero

})
1
Mahipalsinh