web-dev-qa-db-fra.com

iOS TableView recharger et défiler en haut

le deuxième jour je ne peux pas résoudre le problème avec la table.

Nous avons un contrôle segmenté qui, une fois modifié, change le tableau . Supposons qu'il y ait 3 éléments dans le segment du contrôle et, en conséquence, 3 tableaux (ce qui est important, ils ont des tailles différentes) faire défiler le tableau vers le haut lorsque segmentedControl est modifié.

Et il semble que tout soit simple: contentOffset = .zero et reloadData ()

Mais. Cela ne fonctionne pas, je ne sais pas pourquoi la table ne défile pas.

La seule chose qui a fonctionné:

UIView.animate (withDuration: 0.1, animations: {
            self.tableView.contentOffset = .zero
        }) {(_) in
            self.tableView.reloadData ()
}

Mais maintenant, il y a un autre problème lorsque la table remonte, un bogue peut survenir, car le segmentedControl a changé, et les données dans l'autre tableau peuvent ne pas l'être, nous n'avons pas encore terminé reloadData ()

Peut-être que je ne peux pas comprendre les choses évidentes)) Félicitations pour les prochaines vacances!

5
Mikhail Sein

UItableView méthode scrollToRow (at: at: animated :) Fait défiler la vue tabulaire jusqu'à ce qu'une ligne identifiée par chemin d'index se trouve à un emplacement particulier de l'écran.

Utilisation

tableView.scroll(to: .top, animated: true)

Vous pouvez utiliser mon extension

extension UITableView {

    public func reloadData(_ completion: @escaping ()->()) {
        UIView.animate(withDuration: 0, animations: {
            self.reloadData()
        }, completion:{ _ in
            completion()
        })
    }

    func scroll(to: scrollsTo, animated: Bool) {
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
            let numberOfSections = self.numberOfSections
            let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
            switch to{
            case .top:
                if numberOfRows > 0 {
                     let indexPath = IndexPath(row: 0, section: 0)
                     self.scrollToRow(at: indexPath, at: .top, animated: animated)
                }
                break
            case .bottom:
                if numberOfRows > 0 {
                    let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
                    self.scrollToRow(at: indexPath, at: .bottom, animated: animated)
                }
                break
            }
        }
    }

    enum scrollsTo {
        case top,bottom
    }
}
12
AshvinGudaliya

J'ai trouvé un meilleur moyen de le faire. Il fonctionne comme un charme.

let topIndex = IndexPath(row: 0, section: 0)
tableView.scrollToRow(at: topIndex, at: .top, animated: true)
3

vous pouvez l'utiliser.

    tableView.setContentOffset(CGPoint.zero, animated: true)

vous pouvez définir animé comme votre exigence

0
Baltej Singh

J'obtenais l'erreur suivante après avoir essayé de faire défiler vers le haut tout de suite après avoir appelé un reloadData

[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (0) beyond bounds (0) for section (0).'

Cela a résolu le problème pour moi:

    tableView.reloadData()
    if tableView.numberOfRows(inSection: 0) != 0 {
        tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
    }
0
rbaldwin