UITableView прокрутите вниз, чтобы увидеть анимацию вставки - PullRequest
17 голосов
/ 30 сентября 2010

У меня есть UITableView, к которому я добавляю строку с анимацией (используя insertRowsAtIndexPaths:withRowAnimation:).Это все хорошо, если таблица не длиннее экрана.

Если он больше экрана, то я пытаюсь прокрутить до конца, но это не совсем так, как я хочу.Если я добавлю новую строку после добавления, я пропущу анимацию.Если я пытаюсь прокрутить к этому indexPath до того, как он будет добавлен, он выдаст исключение (о том, что он не является допустимым indexPath)

Есть ли решение для этого, кроме добавления пустой строки?

Ответы [ 7 ]

22 голосов
/ 04 декабря 2010

Да, есть решение без добавления пустой строки.

Примечание: в коде я считаю, что есть только 1 раздел, но много строк. Вы можете изменить код для управления несколькими разделами.

- (void)theMethodInWhichYouInsertARowInTheTableView
{
     //Add the object in the array which feeds the tableview
     NSString *newStringObject = @"New Object";
     [arrayWhichFeeds addObject:newStringObject];

     [myTableView beginUpdates]; 

     NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1) inSection:0]];
     [myTableView insertRowsAtIndexPaths:paths withRowAnimation:NO];

     [myTableView endUpdates];
     [myTableView reloadData];
     [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];   
}
20 голосов
/ 25 июля 2012

У меня была такая же проблема.Вот мое решение.

Первый - Обновите свой источник данных

Второй -

NSIndexPath *path = [NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1 inSection:0]];
NSArray *paths = [NSArray arrayWithObject:path];
[myTableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop]; 
[myTableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES];

* Обратите внимание, что это НЕ обернуто в [tableView beginUpdades] и [tableView endUpdates] кодЕсли вы сделаете это, он не будет работать должным образом.

Попробуйте, он должен анимироваться в новых строках снизу при прокрутке к ним.

6 голосов
/ 02 февраля 2013

Другие техники, в том числе упомянутые в этом вопросе, у меня не работали. Это сделал однако:

  1. Добавление нового элемента во внутреннюю коллекцию источника данных.
  2. Установите флаг в элементе, который указывает, что это «новый». Заставьте дисплей ячейки ничего не показывать, когда этот флаг установлен.
  3. Немедленно вызвать tableView: reloadData:
  4. Теперь новый элемент находится в этой таблице, но визуально будет казаться пустым (из-за флага).
  5. Проверьте, видим ли этот новый элемент с помощью tableView.indexPathsForVisibleRows.
  6. Если элемент был на экране, немедленно установите этот «новый» флажок для элемента dataSource в значение NO и вызовите tableView: reloadRowsAtIndexPaths с набором анимации. Теперь это будет выглядеть так, как будто этот элемент был только что добавлен. (вы сделали в этом случае)
  7. Если его не было на экране, прокрутите его на экран с помощью tableView: scrollToRowAtIndexPath: но не вызывайте сразу reloadRowsAtIndexPath ...
  8. Обрабатывать сообщение (void) scrollViewDidEndScrollingAnimation : и делать то же самое reloadRowsAtIndexPath из шага 6. Я подозреваю, что этот метод вызывается каждый раз, когда происходит прокрутка, поэтому вам придется определять, когда он вызывается из шага 7, и когда он вызывается, потому что пользователь прокручивает.

Я разработал эту технику (и написал этот ответ), когда 1-й начал разработку iOS, но это работало в течение длительного времени.

3 голосов
/ 27 апреля 2011

Запомните, чтобы сделать это в главном потоке, иначе он не будет прокручиваться до требуемой позиции.

1 голос
/ 10 января 2017
  1. Обновление источника данных
  2. Вставить строку внизу
  3. Прокрутить вниз

Пример:

YOUR_ARRAY.append("new string")    
tableView.insertRows(at: [IndexPath(row: YOUR_ARRAY.count-1, section: 0)], with: .automatic)
tableView.scrollToRow(at: IndexPath(row: YOUR_ARRAY.count-1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
1 голос
/ 12 августа 2015

Это работает для меня.Вместо того, чтобы вставлять строку, я просто выделяю ее (затухая.) Принцип тот же, однако.

if let definiteIndexPath = indexPathDelegate.getIndexPath(toDoItem) {
    UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {

        self.tableView.scrollToRowAtIndexPath(definiteIndexPath, atScrollPosition: .Middle, animated: false)

        }, completion: {
            (finished: Bool) -> Void in

            // Once the scrolling is done fade the text out and back in.
            UIView.animateWithDuration(5, delay: 1, options: .Repeat | .Autoreverse, animations: {
                self.tableView.reloadRowsAtIndexPaths([definiteIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)

                }, completion: nil)

    })

}
1 голос
/ 12 января 2013

В целом, чтобы прокрутить вниз:

NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.table numberOfRowsInSection:([self.table numberOfSections] - 1)] - 1) inSection:([self.table numberOfSections] - 1)];
[self.table scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...