Dans ma vue tableau, je dois faire défiler vers le haut. Mais je ne peux pas garantir que le premier objet sera la section 0, ligne 0. Peut-être que la vue de mon tableau commencera à la section 5.
Je reçois donc une exception lorsque j'appelle:
[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
Existe-t-il un autre moyen de faire défiler la vue tableau?
UITableView est une sous-classe de UIScrollView, vous pouvez donc également utiliser:
[mainTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
Ou
[mainTableView setContentOffset:CGPointZero animated:YES];
Et à Swift:
mainTableView.setContentOffset(CGPointZero, animated:true)
Et dans Swift 3 et ci-dessus:
mainTableView.setContentOffset(.zero, animated: true)
Je préfère
[mainTableView setContentOffset:CGPointZero animated:YES];
Si vous avez un encart en haut sur votre vue table, vous devez le soustraire:
[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];
Actions possibles:
1
func scrollToFirstRow() {
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}
2
func scrollToLastRow() {
let indexPath = NSIndexPath(forRow: objects.count - 1, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
}
3
func scrollToSelectedRow() {
let selectedRows = self.tableView.indexPathsForSelectedRows
if let selectedRow = selectedRows?[0] as? NSIndexPath {
self.tableView.scrollToRowAtIndexPath(selectedRow, atScrollPosition: .Middle, animated: true)
}
}
4
func scrollToHeader() {
self.tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
}
5
func scrollToTop(){
self.tableView.setContentOffset(CGPointMake(0, UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
}
Désactiver Défilement vers le haut:
func disableScrollsToTopPropertyOnAllSubviewsOf(view: UIView) {
for subview in view.subviews {
if let scrollView = subview as? UIScrollView {
(scrollView as UIScrollView).scrollsToTop = false
}
self.disableScrollsToTopPropertyOnAllSubviewsOf(subview as UIView)
}
}
Modifiez-le et utilisez-le selon vos besoins.
Swift 4
func scrollToFirstRow() {
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
Il vaut mieux ne pas utiliser NSIndexPath (table vide), ni supposer que le point le plus élevé est CGPointZero (encarts de contenu), c'est ce que j'utilise -
[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
J'espère que cela t'aides.
Swift 4 :
Cela fonctionne très bien:
//self.tableView.reloadData() if you want to use this line remember to put it before
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
Pour les tables ayant une contentInset
, définir le contenu du décalage sur CGPointZero
ne fonctionnera pas. Il fera défiler vers le haut le contenu vs défilement vers le haut de la table.
La prise en compte du contenu produit ceci à la place:
[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];
Sous iOS 11, utilisez adjustedContentInset
pour vous déplacer correctement vers le haut dans les deux cas, lorsque la barre d'état en cours d'appel est visible ou non.
if (@available(iOS 11.0, *)) {
[tableView setContentOffset:CGPointMake(0, -tableView.adjustedContentInset.top) animated:YES];
} else {
[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:YES];
}
Rapide:
if #available(iOS 11.0, *) {
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.adjustedContentInset.top), animated: true)
} else {
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
}
Ce code vous permet de faire défiler une section spécifique vers le haut
CGRect cellRect = [tableinstance rectForSection:section];
CGPoint Origin = [tableinstacne convertPoint:cellRect.Origin
fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, Origin.y)];
Rapide:
tableView.setContentOffset(CGPointZero, animated: true)
En ajoutant à ce qui a déjà été dit, vous pouvez créer une extension (Swift) ou une catégorie (Objective C) pour faciliter cela à l'avenir:
Rapide:
extension UITableView {
func scrollToTop(animated: Bool) {
setContentOffset(CGPointZero, animated: animated)
}
}
Chaque fois que vous souhaitez faire défiler une tableView donnée vers le haut, vous pouvez appeler le code suivant:
tableView.scrollToTop(animated: true)
J'ai rencontré un problème lors de l'appel de certaines méthodes sur une tableView
vide. Voici une autre option pour Swift 4 qui gère les vues de table vides.
extension UITableView {
func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section)
}
func scrollToTop(animated: Bool) {
let indexPath = IndexPath(row: 0, section: 0)
if self.hasRowAtIndexPath(indexPath: indexPath) {
self.scrollToRow(at: indexPath, at: .top, animated: animated)
}
}
}
Usage:
// from yourViewController or yourTableViewController
tableView.scrollToTop(animated: true)//or false
Swift 3
tableView.setContentOffset(CGPoint.zero, animated: true)
si tableView.setContentOffset
ne fonctionne pas.
Utilisation:
tableView.beginUpdates()
tableView.setContentOffset(CGPoint.zero, animated: true)
tableView.endUpdates()
Rapide :
si vous n'avez pas d'en-tête tableView:
tableView.setContentOffset(CGPointMake(0, UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
si c'est le cas :
tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
Je préfère ce qui suit, car il prend en compte un encart. S'il n'y a pas d'encart, il défilera toujours vers le haut car l'encart sera 0.
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
Puisque ma tableView
est pleine de toutes sortes d’encarts, c’est la seule chose qui a bien fonctionné:
Swift 3
if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
Swift 2
if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}
Voici ce que j'utilise pour fonctionner correctement sur iOS 11:
extension UIScrollView {
func scrollToTop(animated: Bool) {
var offset = contentOffset
if #available(iOS 11, *) {
offset.y = -adjustedContentInset.top
} else {
offset.y = -contentInset.top
}
setContentOffset(offset, animated: animated)
}
}
NE PAS UTILISER
tableView.setContentOffset(.zero, animated: true)
Il peut parfois régler le décalage de manière incorrecte. Par exemple, dans mon cas, la cellule se situait légèrement au-dessus de la vue avec des zones de sécurité. Pas bon.
INSTEAD USE
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
utiliser contentOffset n'est pas la bonne façon. ce serait mieux car c'est la manière naturelle de table view
tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)
Swift 4 via extension, gère la vue de table vide:
extension UITableView {
func scrollToTop(animated: Bool) {
self.setContentOffset(CGPoint.zero, animated: animated);
}
}
Je devais ajouter la multiplication par -1 *
à la somme de la barre d'état et de la barre de navigation, car la hauteur était dépassée,
self.tableView.setContentOffset(CGPointMake(0 , -1 *
(self.navigationController!.navigationBar.height +
UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)
func scrollToTop() {
NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
[tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
appelez cette fonction où vous voulez UITableView faites défiler vers le haut
Ce fut le seul extrait de code qui a fonctionné pour moi
Swift 4:
tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
tableView.setContentOffset(CGPoint(x: 0, y: -70), animated: true)
P.S. 70 est la hauteur de ma cellule d'en-tête et de table
Dans Swift 5, Merci @ Adrian répond beaucoup
extension UITableView{
func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
return indexPath.section < numberOfSections && indexPath.row < numberOfRows(inSection: indexPath.section)
}
func scrollToTop(_ animated: Bool = false) {
let indexPath = IndexPath(row: 0, section: 0)
if hasRowAtIndexPath(indexPath: indexPath) {
scrollToRow(at: indexPath, at: .top, animated: animated)
}
}
}
Usage:
tableView.scrollToTop()
Voici le code pour faire défiler TableView To Top par programme
Rapide:
self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)
Dans Swift-3:
self.tableView.setContentOffset(CGPoint.zero, animated: true)
J'utilise tabBarController et j'ai quelques sections dans ma tableview à chaque onglet, donc c'est la meilleure solution pour moi.
extension UITableView {
func scrollToTop(){
for index in 0...numberOfSections - 1 {
if numberOfSections > 0 && numberOfRows(inSection: index) > 0 {
scrollToRow(at: IndexPath(row: 0, section: index), at: .top, animated: true)
break
}
if index == numberOfSections - 1 {
setContentOffset(.zero, animated: true)
break
}
}
}
}
Pour avoir une fin lorsque vous avez terminé, ajoutez cette extension
// MARK: - UIScrollView
extension UIScrollView {
/// Animate scroll to top with completion
///
/// - Parameters:
/// - duration: TimeInterval
/// - completion: Completion block
func animateScrollToTop(withDuration duration: TimeInterval,
completion: @escaping (()->())) {
UIView.animate(withDuration: duration, animations: { [weak self] in
self?.setContentOffset(CGPoint.zero, animated: false)
}, completion: { finish in
guard finish else {
return
}
completion()
})
}
}
tableView.animateScrollToTop(withDuration: 0.25) {
// Finish
}
Si vous souhaitez déplacer une animation de défilement dans le tableau, utilisez ce code. Le défilement se déplace vers le haut avec animation en 0.5 secondes.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[_tableContent scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
[UIView commitAnimations];
à Swift
votre ligne = selectioncellRowNumber votre section si vous avez = selectionNumber si vous n'avez pas défini est à zéro
//UITableViewScrollPosition.Middle ou Bottom ou Top
var lastIndex = NSIndexPath(forRow: selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
Avec Swift:
self.scripSearchView.quickListTbl?.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)