J'ai dans iOS8 une vue de table comme celle-ci:
tableView = UITableView(frame: view.bounds, style: .Plain)
view.addSubview(tableView)
Lorsque l'utilisateur tape et envoie du texte au clavier, l'application applique la méthode suivante pour faire défiler la table. Le but est de voir le nouveau texte à l'écran (comme un chat)
let numberOfRows = tableView.numberOfRowsInSection(0)
if numberOfRows > 0 {
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: 0)
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
Mais la vue sous forme de tableau ne fait pas défiler jusqu'au démarrage.
Quelqu'un a une solution?
Je vous remercie.
Explication:
Définition de la classe:
class ChatViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextViewDelegate
alors j'ai la définition de la vue tableau:
var tableView: UITableView!
dans viewDidLoad:
tableView = UITableView(frame: view.bounds, style: .Plain)
tableView.dataSource = self
tableView.delegate = self
view.addSubview(tableView)
puis j'ai l'appel du code qui doit faire défiler (deuxième bloc de code sur ma réponse). Lorsque je lance l’application, la vue table doit défiler vers le bas, mais cela ne fonctionne pas.
La solution ci-dessous a fonctionné pour moi. C'est une combinaison de solutions trouvées sur StackOverflow. J'ai appelé "scrollToRowAtIndexPath
" après un très bref délai.
func tableViewScrollToBottom(animated: Bool) {
let delay = 0.1 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
let numberOfSections = self.tableView.numberOfSections()
let numberOfRows = self.tableView.numberOfRowsInSection(numberOfSections-1)
if numberOfRows > 0 {
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
})
}
appelé par :
tableViewScrollToBottom(true)
Swift 3
func tableViewScrollToBottom(animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
let numberOfSections = self.tableView.numberOfSections
let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: animated)
}
}
}
La solution à mon problème est la suivante:
let numberOfSections = tableView.numberOfSections()
let numberOfRows = tableView.numberOfRowsInSection(numberOfSections-1)
if numberOfRows > 0 {
println(numberOfSections)
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
Essayez de recharger avant d'appeler Scroll. Très bizarre mais fonctionne pour iOS 8.
tableView.reloadData()
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
Swift 3 VERSION de @ Fox5150 answer, avec une extension:
extension UITableView {
func tableViewScrollToBottom(animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
let numberOfSections = self.numberOfSections
let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
self.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: animated)
}
}
}
}
UTILISATION:
self.tableView.tableViewScrollToBottom(animated: true)
J'ai le problème avec un index plus grand, disons même 15. Seuls les index jusqu'à 5-6 utilisent pour fonctionner. En faisant "animated: false", scrollToRowAtIndexPath () fonctionnait parfaitement.
La meilleure solution consiste à retourner la tableView afin que vous puissiez afficher le nouveau message simplement par -insertRowsAtIndexPaths:withRowAnimation:
pour le faire, vous devez d'abord retourner votre table en:
_tableView.transform = CGAffineTransformMakeScale (1,-1);
alors n'oubliez pas de retourner vos cellules, le meilleur endroit pour le faire dans -awakeFromNib en sous-classant:
- (void)awakeFromNib {
[super awakeFromNib];
self.contentView.transform = CGAffineTransformMakeScale (1,-1);
//if you have accessoryView
self.accessoryView.transform = CGAffineTransformMakeScale (1,-1);
}
C'est simple. Il suffit de faire l'opération de défilement dans viewDidLayoutSubViews ()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.scrollToBottom(animated: false)
}
fileprivate func scrollToBottom(animated: Bool) {
if self.items.count > 0 {
let lastIndex = IndexPath(row: items.count - 1, section: 1)
self.tableView.scrollToRow(at: lastIndex, at: .bottom, animated: animated)
}
}
Il semble que tableview puisse obtenir la bonne position après les sous-vues de la présentation.
Si le clavier est toujours visible, vous devez définir la propriété UITableView
de contentInset
pour compenser la hauteur du clavier en bas de l'écran. Sinon, votre cellule pourrait être cachée derrière le clavier car la UITableView
ne sait pas que la moitié de son contenu est cachée par elle.
Ou utilisez une UITableViewController
qui gère cela automatiquement.
Je sais que c'est un fil plus ancien, mais il reste pertinent. Au lieu de gérer des délais qui pourraient parfois échouer, utilisez des blocs synchrones sur le thread principal (normalement, ce n’est pas ce que je ferais, mais nous parlons en millisecondes):
DispatchQueue.main.sync {
// Reload code goes here...
tableView.reloadData()
}
DispatchQueue.main.sync {
// Row, section and other checks / initialization go here...
tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
Cela fonctionne toujours pour moi.
Heres Swift 3 version
let numberOfSections = self.tableView.numberOfSections
let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = NSIndexPath.init(row: numberOfRows-1, section: numberOfSections-1)
self.tableView.scrollToRow(at: indexPath as IndexPath, at: UITableViewScrollPosition.bottom, animated: animated)
}
Appelez la méthode scrollToLastPosition () après le chargement de la vue table comme un appel de viewWillAppear () ou après le rechargement de la vue table lorsque quelque chose a changé en vue table
func scrollToLastPosition() {
if !message.isEmpty {
let indexpath = NSIndexPath(forRow: message.count - 1 , inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexpath, atScrollPosition: .Bottom, animated: true)
}
}
// First figure out how many sections there are
let lastSectionIndex = self.tblTableView!.numberOfSections() - 1
// Then grab the number of rows in the last section
let lastRowIndex =
self.tblTableView!.numberOfRowsInSection(lastSectionIndex) - 1
// Now just construct the index path
let pathToLastRow = NSIndexPath(forRow: lastRowIndex, inSection: lastSectionIndex)
// Make the last row visible
self.tblTableView?.scrollToRowAtIndexPath(pathToLastRow, atScrollPosition: UITableViewScrollPosition.None, animated: true)