Ich habe eine UITableView
mit cells
, die dynamisch aktualisiert wird. Alles funktioniert gut, außer wenn tableview.reload
aufgerufen wird (siehe unten), um die cells
in der Tabelle zu aktualisieren.
- (void)reloadTable:(NSNotification *)notification {
NSLog(@"RELOAD TABLE ...");
[customTableView reloadData];
// Scroll to bottom of UITable here ....
}
Ich plante, scrollToRowAtIndexPath:atScrollPosition:animated:
zu verwenden, bemerkte dann jedoch, dass ich keinen Zugriff auf eine indexPath
habe.
Weiß jemand, wie das geht, oder von einem delegate
-Rückruf, den ich verwenden könnte?
Benutzen:
NSIndexPath* ipath = [NSIndexPath indexPathForRow: cells_count-1 inSection: sections_count-1];
[tableView scrollToRowAtIndexPath: ipath atScrollPosition: UITableViewScrollPositionTop animated: YES];
Oder Sie können den Abschnittsindex manuell angeben (Wenn ein Abschnitt => Index = 0).
Eine andere Lösung besteht darin, den Tisch vertikal zu spiegeln und jede Zelle vertikal zu spiegeln:
Wenden Sie die Transformation bei der Initialisierung auf die UITableView an:
tableview.transform = CGAffineTransformMakeScale(1, -1);
und in cellForRowAtIndexPath:
cell.transform = CGAffineTransformMakeScale(1, -1);
Auf diese Weise benötigen Sie keine Problemumgehungen für Bildlaufprobleme, Sie müssen jedoch etwas mehr über contentInsets/contentOffsets und die Kopf-/Fußzeile-Interaktionen nachdenken.
-(void)scrollToBottom{
[self.tableView scrollRectToVisible:CGRectMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height, self.tableView.bounds.size.width, self.tableView.bounds.size.height) animated:YES];
}
//In Swift
var iPath = NSIndexPath(forRow: self.tableView.numberOfRowsInSection(0)-1,
inSection: self.tableView.numberOfSections()-1)
self.tableView.scrollToRowAtIndexPath(iPath,
atScrollPosition: UITableViewScrollPosition.Bottom,
animated: true)
Dies ist eine andere Lösung, die in meinem Fall gut funktioniert hat, wenn die Zellenhöhe groß ist.
- (void)scrollToBottom
{
CGPoint bottomOffset = CGPointMake(0, _bubbleTable.contentSize.height - _bubbleTable.bounds.size.height);
if ( bottomOffset.y > 0 ) {
[_bubbleTable setContentOffset:bottomOffset animated:YES];
}
}
Da dies etwas ist, das Sie häufig verwenden möchten, sollten Sie eine Klassenerweiterung in UITableView erstellen:
extension UITableView {
func scrollToBottom(animated: Bool = true) {
let section = self.numberOfSections
if section > 0 {
let row = self.numberOfRowsInSection(section - 1)
if row > 0 {
self.scrollToRowAtIndexPath(NSIndexPath(forRow: row - 1, inSection: section - 1), atScrollPosition: .Bottom, animated: animated)
}
}
}
}
die Erweiterung ist besser für UIScrollView anstelle von UITableView auszuführen. Auf diese Weise funktioniert sie für ScrollView, TableView, CollectionView (vertikal), UIWebView (innere Scrollansicht) usw.
public extension UIScrollView {
public func scrollToBottom(animated animated: Bool) {
let rect = CGRectMake(0, contentSize.height - bounds.size.height, bounds.size.width, bounds.size.height)
scrollRectToVisible(rect, animated: animated)
}
}
Swift 3
Für alle, die versuchen, herauszufinden, wie dieses Problem gelöst werden kann, müssen Sie die .layoutIfNeeded()
-Methode nach .reloadData()
aufrufen:
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.height), animated: false)
Ich arbeitete mit mehreren Abschnitten in UITableView
und es hat gut funktioniert.
Das ist der beste Weg.
- (void)scrollToBottom
{
CGFloat yOffset = 0;
if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
}
[self.tableView setContentOffset:CGPointMake(0, yOffset) animated:NO];
}
versuchen Sie diesen Code, es kann Ihnen helfen:
self.tableView.reloadData()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.1, execute: {
let indexPath = IndexPath(row: self.dateSource.count-1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: true)
})
Swift 5
func scrollToBottom() {
let section = self.tableView.numberOfSections
let row = self.tableView.numberOfRows(inSection: self.tableView.numberOfSections - 1) - 1;
guard (section > 0) && (row > 0) else{ // check bounds
return
}
let indexPath = IndexPath(row: row-1, section: section-1)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
Ich bin nicht einverstanden, dass wir cells_count
, sections_count
, self.dateSource.count
verwenden sollten und so weiter. Stattdessen wird der Delegierte besser sein.
Fot Swift 5
extension UITableView {
func scrollToBottom(animated: Bool = true) {
let section = self.numberOfSections
if section > 0 {
let row = self.numberOfRows(inSection: section - 1)
if row > 0 {
self.scrollToRow(at: IndexPath(row: row-1, section: section-1), at: .bottom, animated: animated)
}
}
}
}