Есть ли способ узнать, отображается ли в данный момент ячейка таблицы? У меня есть tableview, чья первая ячейка (0) является uisearchbar. Если поиск не активен, то спрячьте ячейку 0 через смещение. Когда таблица имеет только несколько строк, строка 0 видна. Как определить, является ли строка 0 видимой или является верхней строкой?
Определите, видна ли ячейка таблицы.
Ответ 1
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
, который возвращает массив объектов ячейки таблицы. Объекты ячеек таблицы возвращаются, поэтому в больших таблицах они, в конечном счете, не будут иметь простой корреляции с вашим источником данных.
Ответ 2
Чтобы проверить ячейку tableview видна или не использовать этот код строки
if(![tableView.indexPathsForVisibleRows containsObject:newIndexPath])
{
// your code
}
здесь newIndexPath является IndexPath проверки ячейки.....
Swift 3.0
if !(tableView.indexPathsForVisibleRows?.contains(newIndexPath)) {
// Your code here
}
Ответ 3
Я использую это в 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 }
} }
Ответ 4
Другое решение (которое также может быть использовано для проверки полноты видимости строки) должно было бы проверить, находится ли кадр для 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
}
Ответ 5
Быстрая версия:
if let indices = tableView.indexPathsForVisibleRows {
for index in indices {
if index.row == 0 {
return true
}
}
}
return false
Ответ 6
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)
{
Ответ 7
Обратите внимание, что "несколько видимое" является "видимым". Кроме того, в viewWillAppear вы можете получить ложные срабатывания от indexPathsForVisibleRows
по мере того, как макет выполняется, и если вы смотрите на последнюю строку, даже вызов layoutIfNeeded()
не поможет вам для таблиц. Вы захотите проверить все в/после viewDidAppear
.
Этот быстрый код 3.1 отключит прокрутку, если последняя строка будет полностью видимой. Вызовите его в/после просмотраDidAppear.
let numRows = tableView.numberOfRows(inSection: 0) // this can't be in viewWillAppear because the table 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
}