2013-03-04 97 views

回答

13

使用indexPathsForVisibleRows的問題是它不包含沒有任何行的部分。要獲取所有可見部分(包括空白部分),必須檢查該部分的矩形並將其與表的contentOffset進行比較。

您還必須注意普通樣式與浮動部分之間的區別以及沒有浮動部分的分組樣式。

我做了一個類別支持此計算:

@interface UITableView (VisibleSections) 

// Returns an array of NSNumbers of the current visible section indexes 
- (NSArray *)indexesOfVisibleSections; 
// Returns an array of UITableViewHeaderFooterView objects of the current visible section headers 
- (NSArray *)visibleSections; 

@end 

@implementation UITableView (VisibleSections) 

- (NSArray *)indexesOfVisibleSections { 
    // Note: We can't just use indexPathsForVisibleRows, since it won't return index paths for empty sections. 
    NSMutableArray *visibleSectionIndexes = [NSMutableArray arrayWithCapacity:self.numberOfSections]; 
    for (int i = 0; i < self.numberOfSections; i++) { 
     CGRect headerRect; 
     // In plain style, the section headers are floating on the top, so the section header is visible if any part of the section's rect is still visible. 
     // In grouped style, the section headers are not floating, so the section header is only visible if it's actualy rect is visible. 
     if (self.style == UITableViewStylePlain) { 
      headerRect = [self rectForSection:i]; 
     } else { 
      headerRect = [self rectForHeaderInSection:i]; 
     } 
     // The "visible part" of the tableView is based on the content offset and the tableView's size. 
     CGRect visiblePartOfTableView = CGRectMake(self.contentOffset.x, self.contentOffset.y, self.bounds.size.width, self.bounds.size.height); 
     if (CGRectIntersectsRect(visiblePartOfTableView, headerRect)) { 
      [visibleSectionIndexes addObject:@(i)]; 
     } 
    } 
    return visibleSectionIndexes; 
} 

- (NSArray *)visibleSections { 
    NSMutableArray *visibleSects = [NSMutableArray arrayWithCapacity:self.numberOfSections]; 
    for (NSNumber *sectionIndex in self.indexesOfVisibleSections) { 
     UITableViewHeaderFooterView *sectionHeader = [self headerViewForSection:sectionIndex.intValue]; 
     [visibleSects addObject:sectionHeader]; 
    } 

    return visibleSects; 
} 

@end 
4

對於一個普通的樣式表,就可以得到可見行。從這些,獲取可見部分的集合。然後,從表中獲取節標題視圖。

NSArray *visibleRows = [self.tableView indexPathsForVisibleRows]; 
NSMutableIndexSet *sections = [[NSMutableIndexSet alloc] init]; 
for (NSIndexPath *indexPath in visibleRows) { 
    [sections addIndex:indexPath.section]; 
} 

NSMutableArray *headerViews = [NSMutableArray array]; 
[sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 
    UIView *view = [self.tableView headerViewForSection:idx]; 
    [headerViews addObject:view]; 
}]; 

注意:未經測試的代碼 - 可能包含拼寫錯誤。這對分組樣式表不起作用。

+1

如果該部分沒有行 – 2013-11-06 15:36:57

+1

@PeterLapisu不起作用不起作用但您不應該爲沒有行的部分顯示節標題,所以這不會成爲問題。 – rmaddy 2013-11-06 16:30:50

+1

取決於的情況下,我剛剛遇到這種情況:)) – 2013-11-06 20:39:10

1

在這種情況下,我想你設置cell.tagcellForRowAtIndexPath當前節(indexPath.section)和像你描述和headerViewForSection使用visibleCells方法。

6

我真的很喜歡@ adamsiton的解決方案,我最終將其轉換成快捷。這是FYI。

我叫做文件的UITableView + VisibleSections.swift

import UIKit 

public extension UITableView { 

    var indexesOfVisibleSections: [Int] { 
     // Note: We can't just use indexPathsForVisibleRows, since it won't return index paths for empty sections. 
     var visibleSectionIndexes = [Int]() 

     for i in 0..<numberOfSections { 
      var headerRect: CGRect? 
      // In plain style, the section headers are floating on the top, so the section header is visible if any part of the section's rect is still visible. 
      // In grouped style, the section headers are not floating, so the section header is only visible if it's actualy rect is visible. 
      if (self.style == .plain) { 
       headerRect = rect(forSection: i) 
      } else { 
       headerRect = rectForHeader(inSection: i) 
      } 
      if headerRect != nil { 
       // The "visible part" of the tableView is based on the content offset and the tableView's size. 
       let visiblePartOfTableView: CGRect = CGRect(x: contentOffset.x, y: contentOffset.y, width: bounds.size.width, height: bounds.size.height) 
       if (visiblePartOfTableView.intersects(headerRect!)) { 
        visibleSectionIndexes.append(i) 
       } 
      } 
     } 
     return visibleSectionIndexes 
    } 

    var visibleSectionHeaders: [UITableViewHeaderFooterView] { 
     var visibleSects = [UITableViewHeaderFooterView]() 
     for sectionIndex in indexesOfVisibleSections { 
      if let sectionHeader = headerView(forSection: sectionIndex) { 
       visibleSects.append(sectionHeader) 
      } 
     } 

     return visibleSects 
    } 
} 
2

本傑明·惠勒的解決方案是一個偉大的迅速解決。由於新的Swift語法,我修復了一個問題,並修改它以匹配默認UITableView實現提供的.visibleCells屬性。

extension UITableView { 

    /// The table section headers that are visible in the table view. (read-only) 
    /// 
    /// The value of this property is an array containing UITableViewHeaderFooterView objects, each representing a visible cell in the table view. 
    /// 
    /// Derived From: [http://stackoverflow.com/a/31029960/5191100](http://stackoverflow.com/a/31029960/5191100) 
    var visibleSectionHeaders: [UITableViewHeaderFooterView] { 
     get { 
      var visibleSects = [UITableViewHeaderFooterView]() 

      for sectionIndex in indexesOfVisibleSections() { 
       if let sectionHeader = self.headerViewForSection(sectionIndex) { 
        visibleSects.append(sectionHeader) 
       } 
      } 

      return visibleSects 
     } 
    } 

    private func indexesOfVisibleSections() -> Array<Int> { 
     // Note: We can't just use indexPathsForVisibleRows, since it won't return index paths for empty sections. 
     var visibleSectionIndexes = Array<Int>() 

     for (var i = 0; i < self.numberOfSections; i++) { 
      var headerRect: CGRect? 
      // In plain style, the section headers are floating on the top, 
      // so the section header is visible if any part of the section's rect is still visible. 
      // In grouped style, the section headers are not floating, 
      // so the section header is only visible if it's actual rect is visible. 
      if (self.style == .Plain) { 
       headerRect = self.rectForSection(i) 
      } else { 
       headerRect = self.rectForHeaderInSection(i) 
      } 

      if headerRect != nil { 
       // The "visible part" of the tableView is based on the content offset and the tableView's size. 
       let visiblePartOfTableView: CGRect = CGRect(
        x: self.contentOffset.x, 
        y: self.contentOffset.y, 
        width: self.bounds.size.width, 
        height: self.bounds.size.height 
       ) 

       if (visiblePartOfTableView.intersects(headerRect!)) { 
        visibleSectionIndexes.append(i) 
       } 
      } 
     } 

     return visibleSectionIndexes 
    } 
} 
1

得到當前可見的部分,U可以通過檢查目前可見的細胞indexpath節得到它,所以這個功能可以返回到u可見部分

- (NSArray *)indexesOfVisibleSections { 

    NSMutableArray *visibleSections = [NSMutableArray array]; 

    for (UITableViewCell * cell in [self.tableView visibleCells]) { 
     if (![visibleSections containsObject:[NSNumber numberWithInteger:[self.tableView indexPathForCell:cell].section]]) { 
      [visibleSections addObject:[NSNumber numberWithInteger:[self.tableView indexPathForCell:cell].section]]; 
     } 
    } 

    return visibleSections; 
} 

並訪問剖面圖, ü可以使用

- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section; 
+0

不包含不包含單元格的標頭 – kgaidis 2016-04-12 01:54:08

+0

@kgaidis你有沒有測試過它?這裏的邏輯是它得到可見的單元部分,不管它是什麼類型的,所以如果你有3個部分,每個部分都有1行,那麼它檢查可見的行數組,並且獲取這些行部分並將其添加到可見部分的數組中,它與節頭類型,視圖或單元無關 – Mortgy 2016-04-17 11:11:06

+0

「每個都有1行」。那是失敗的地方。一個部分可以存在,並且標題視圖可見,它沒有單元格。如果一個部分沒有單元格,那麼它將不會是'visibleCells'的一部分,這是該算法完全依賴的。 – kgaidis 2016-04-17 13:23:32

0

就讓我們來看看在UITableView文件給我們的indexPathsForVisibleRows並將其與地圖相結合爲我們提供了我們網元,該陣列編輯:

tableView.indexPathsForVisibleRows.map{ tableView.headerView(forSection: $0.section) } 

地圖返回我們可見的標題段的數組。

相關問題