2017-02-23 50 views
1

У меня есть UITableView с примерно 500 наименованиями.TableView scrollToRow блокирует основную нить ui

Когда я звоню tableView.scrollToRow(at: indexPath, at: .bottom, animated: false), основной поток пользовательского интерфейса блокируется в течение 3 секунд.

Есть ли способ исправить это? или проблема с прокруткой 500 предметов?

Благодаря


проблема не с reloadData это было с scrollToRow

+0

Вы должны использовать ленивую загрузку. Это поможет вам более гладкий свиток. –

+0

Можете ли вы показать свой код? – Sneha

+0

@kayzersoze, что должно быть ленивым? tableView? – ilan

ответ

2

Из дискуссии о том, как использовать табличную для чата: Мы можем использовать вид таблицы, которая использует преобразование, чтобы перевернуть Y координат. Затем нам нужно сделать то же самое для каждой из ячеек, чтобы они не перевернулись.

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

chatContainer?.transform = CGAffineTransform(scaleX: 1.0, y: -1.0) 

Кювета сообщения должны также иметь какое-то надтаблицы для всего содержимого, который нужно перевернуть:

override func awakeFromNib() { 
     super.awakeFromNib() 

     containerView?.transform = CGAffineTransform(scaleX: 1.0, y: -1.0) 
    } 

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

Вы можете найти пример проекта here.

+0

Большое вам спасибо ... отлично работает. – ilan

+0

Один комментарий, вы можете преобразовать ячейки, и tableView сами не нужно преобразовывать контейнеры. – ilan

+0

Я знаю, что вы можете, но я отговариваю вас от этого. Вид таблицы может внутренне выполнять некоторые настройки непосредственно с ячейками, которые затем могут прерываться, если вы назначаете им преобразование. То же самое относится ко всему представлению таблицы. Поэтому, пожалуйста, используйте это с осторожностью. –

0

Используйте профайлер, чтобы определить, где именно проблема. Дело в том, что в целом производительность UITableView не выполняется множеством загруженных элементов. В самом представлении будет загружено столько элементов, сколько необходимо для заполнения всего экрана.

Вы можете проверить это, зарегистрировав метод в cellForRowAtIndexPath. Поэтому я предполагаю, что этот метод может быть медленным. Проверьте, как вы получаете доступ к данным из него, может быть, есть какая-то тяжелая логика. Или макет ячейки может быть прослушанным и очень медленным.

В общем случае, если у вас очень большой объем данных, используйте данные ядра и NSFetchedResultsController, который специально разработан для этой ситуации. Но все же обратите внимание, что загрузка 500 элементов в виде таблицы должна работать плавно без каких-либо специальных оптимизаций.

+0

Спасибо, моя ошибка, что блок не был из reloadData. После загрузки я прокручиваю нижнюю часть таблицыView и блокирует поток. tableView.scrollToRow (at: indexPath, at: .bottom, animated: false) – ilan

+0

Любые предложения, как исправить это? – ilan

+0

Хорошо, что это может быть проблемой. У вас есть фиксированные высоты ячеек? Возможно, попробуйте вручную вычислить смещение и используйте setContentOffset. Я не уверен, что это исправит, но попытайтесь. –

0

Вы должны сделать что-то подобное; Если пользователь прокручивает вниз сверху вниз метод делегата scrollview tableview, запустите его метод scrollViewDidScroll и определите, находится ли пользователь внизу таблицы или нет, затем выберите другие данные и добавьте массив и перезапустите tableview. Это оно!

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    CGFloat actualPosition = scrollView_.contentOffset.y; 
    CGFloat contentHeight = scrollView_.contentSize.height - (someArbitraryNumber); 
    if (actualPosition >= contentHeight) { 
     [self.newsFeedData_ addObjectsFromArray:self.newsFeedData_]; 
     [self.tableView reloadData]; 
    } 
} 
+0

, это не очень хорошая идея, вы будете испытывать отставание от прокрутки и вообще, почему бы вам перезагрузить все данные в любом событии прокрутки. это заморозит приложение еще больше – zero3nna

0

Я не уверен на 100% об этом решении, у меня не было этой проблемы. Может быть, просто отправьте его?

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) 
      } 
     } 
    } 
} 
+1

не должен ли свиток быть на нитке ui? – ilan

+0

да, вот и проблема у меня с этим тоже. Ты это пробовал? С другой стороны, вы не оживляете его. Я видел несколько примеров, отправляющих его (http://stackoverflow.com/questions/26244293/scrolltorowatindexpath-with-uitableview-does-not-work), но я не могу проверить это прямо сейчас. – zero3nna

+0

не работает. он не прокручивается, а затем, когда пользователь прокручивает его, сбой с какой-либо проблемой потока – ilan