Определите, видна ли ячейка таблицы - PullRequest
53 голосов
/ 24 июля 2010

Есть ли способ узнать, видна ли в данный момент ячейка таблицы? У меня есть табличное представление, чья первая ячейка (0) является панелью пользователя. Если поиск не активен, то скрыть ячейку 0 через смещение. Когда в таблице всего несколько строк, строка 0 видна. Как определить, видна ли строка 0 или есть верхняя строка?

Ответы [ 7 ]

98 голосов
/ 25 июля 2010

UITableView имеет метод экземпляра с именем indexPathsForVisibleRows, который будет возвращать NSArray из NSIndexPath объектов для каждой строки в таблице, которые в данный момент видны.Вы можете проверить этот метод с любой необходимой вам частотой и проверить правильность строки.Например, если tableView является ссылкой на вашу таблицу, следующий метод скажет вам, отображается ли строка 0 на экране:

-(BOOL)isRowZeroVisible {
  NSArray *indexes = [tableView indexPathsForVisibleRows];
  for (NSIndexPath *index in indexes) {
    if (index.row == 0) {
      return YES;
    }
  }

  return NO;
}

Поскольку метод UITableView возвращает NSIndexPath,Вы также можете легко расширить это, чтобы искать разделы или комбинации строк / разделов.

Это более полезно для вас, чем метод visibleCells, который возвращает массив объектов ячейки таблицы.Объекты ячеек таблиц перерабатываются, поэтому в больших таблицах они в конечном итоге не будут иметь простой корреляции с вашим источником данных.

40 голосов
/ 09 октября 2012

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

    if(![tableView.indexPathsForVisibleRows containsObject:newIndexPath])
    {
       // your code 
    }

здесь newIndexPath - это IndexPath проверки ячейки .....

Swift 3.0

if !(tableView.indexPathsForVisibleRows?.contains(newIndexPath)) {
  // Your code here

}
13 голосов
/ 17 января 2017

Я использую это в Swift 3.0

extension UITableView {

    /// Check if cell at the specific section and row is visible
    /// - Parameters:
    /// - section: an Int reprenseting a UITableView section
    /// - row: and Int representing a UITableView row
    /// - Returns: True if cell at section and row is visible, False otherwise
    func isCellVisible(section:Int, row: Int) -> Bool {
        guard let indexes = self.indexPathsForVisibleRows else {
            return false
        }
        return indexes.contains {$0.section == section && $0.row == row }
    }  }
5 голосов
/ 07 ноября 2015

Swift Версия:

if let indices = tableView.indexPathsForVisibleRows {
    for index in indices {
        if index.row == 0 {
            return true
        }
    }
}
return false
4 голосов
/ 12 ноября 2013

Другое решение (которое также можно использовать для проверки, полностью ли видна строка) - проверить, находится ли рамка для row внутри видимого прямоугольника tableview.

В следующем коде ip представляет NSIndexPath:

CGRect cellFrame = [tableView rectForRowAtIndexPath:ip];
if (cellFrame.origin.y<tableView.contentOffset.y) { // the row is above visible rect
  [tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
else if(cellFrame.origin.y+cellFrame.size.height>tableView.contentOffset.y+tableView.frame.size.height-tableView.contentInset.top-tableView.contentInset.bottom){ // the row is below visible rect
  [tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}

Также должно работать cellForRowAtIndexPath:, поскольку оно возвращает объект nil, если строка не видна:

if([tableView cellForRowAtIndexPath:ip]==nil){
  // row is not visible
}
1 голос
/ 29 марта 2011

IOS 4:

NSArray *cellsVisible = [tableView indexPathsForVisibleRows];
NSUInteger idx = NSNotFound;
idx = [cellsVisible indexOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
{
    return ([(NSIndexPath *)obj compare:indexPath] == NSOrderedSame);
}];

if (idx == NSNotFound)
{
0 голосов
/ 31 марта 2017

Обратите внимание, что «Несколько видимый» является «видимым». Кроме того, в viewWillAppear вы можете получить ложные срабатывания от indexPathsForVisibleRows во время разметки, и если вы смотрите на последнюю строку, даже вызов layoutIfNeeded() не поможет вам для таблиц. Вы хотите проверить вещи в / после viewDidAppear.

Этот код swift 3.1 отключит прокрутку, если последняя строка полностью видна. Вызовите его в / после viewDidAppear.

    let numRows = tableView.numberOfRows(inSection: 0) // this can't be in viewWillAppear because the table's frame isn't set to proper height even after layoutIfNeeded()
    let lastRowRect = tableView.rectForRow(at: IndexPath.init(row: numRows-1, section: 0))
    if lastRowRect.origin.y + lastRowRect.size.height > tableView.frame.size.height {
        tableView.isScrollEnabled = true
    } else {
        tableView.isScrollEnabled = false
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...