可重用的TableView标题视图

Ily*_*ski 29 iphone cocoa-touch

出于性能考虑,通常会重用UITableView的单元格.有没有办法用TableView标题'视图做同样的事情?我在谈论用委托方法返回的那些:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
Run Code Online (Sandbox Code Playgroud)

我尝试执行以下操作,但似乎没有按预期工作:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *CellIdentifier = @"Header";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
    if (cell == nil) {
        cell = [self getHeaderContentView: CellIdentifier];
    }
    return cell;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法重用标题'的观点?

Mar*_*don 34

Apple构建重用tableview单元的能力的原因是因为虽然tableview可能有很多行,但屏幕上只显示少数行.应用程序可以重用已有的单元并根据需要重新配置,而不是为每个单元分配内存.

首先,标题视图只是UIViews,而UITableViewCell是UIView的子类,它们并不打算作为节标题的视图放置.

此外,由于您通常会有比总行数少得多的节标题,因此没有理由建立可重用性机制,事实上Apple没有为通用UIView实现一个.

请注意,如果您只是为标题设置标签,则可以-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section改为使用.

对于更自定义的内容,例如带有红色文本的标签(或按钮,图像等),您可以执行以下操作:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 44)] autorelease];
  UILabel *label = [[[UILabel alloc] initWithFrame:headerView.frame] autorelease];
  label.textColor = [UIColor redColor];
  label.text = [NSString stringWithFormat:@"Section %i", section];

  [headerView addSubview:label];
  return headerView;
}
Run Code Online (Sandbox Code Playgroud)

  • "没有理由建立可重用性机制......"马丁斯的评论通常是正确的,但并非完全正确.对于那些试图达到60fps(像我一样)的人来说,带有自定义视图的viewForHeaderInSection是魔鬼.为每个标题添加一个新视图,特别是如果您的组不大,实际上将无法达到所述性能,因为它通常会花费我5 FPS.如果您可以避免设计中的自定义标题,它将为您带来性能提升. (15认同)
  • 即使您的解释是彻底的,但这实际上并没有回答这个问题. (3认同)
  • 但是,如果您真的需要使用自定义标题视图,那么将FPS保持在60的最佳方法是什么? (2认同)
  • 从iOS 6开始,我们也应该重用它们:`UITableViewHeaderFooterView` (2认同)

小智 12

您可以通过创建UITableViewHeaderFooterView类来实现它,它是UIView的子类 您还需要创建一个单独的XIB,因为它不会在创建UITableViewHeaderFooterView时自动创建.

使用tableview注册Nib

[self.tblCart registerNib:[UINib nibWithNibName:@"CartHeaderView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"CartHeader"];
Run Code Online (Sandbox Code Playgroud)

现在您可以在viewForHeaderInSection中访问它

-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{

    CartHeaderView *sectionHeader=[tableView dequeueReusableHeaderFooterViewWithIdentifier:@"CartHeader"];
 return sectionHeader;
}
Run Code Online (Sandbox Code Playgroud)

注意:要设置背景颜色,您需要创建一个子视图,其框架与节标题相同,并为该视图设置颜色.

你可以关注

更改从xib加载的UITableViewHeaderFooterView上的背景颜色表示使用contentView.backgroundColor代替


Kos*_*sky 10

简单而有效的解决方案:

@interface SectionedTableViewController ()
    @property (nonatomic, strong) UINib*          sectionHeaderNib;
    @property (nonatomic, strong) NSMutableArray* sectionHeaders;
@end

@implementation SectionedTableViewController

@synthesize sectionHeaderNib = sectionHeaderNib_;
@synthesize sectionHeaders = sectionHeaders_;

- (void) viewDidUnload
{
    self.sectionHeaders = nil;
    [super viewDidUnload];
}

- (NSMutableArray*) sectionHeaders
{
    if (!sectionHeaders_)
        self.sectionHeaders = [NSMutableArray array];
    return sectionHeaders_;
}


- (UINib*) sectionHeaderNib
{
    if (!sectionHeaderNib_)
        self.sectionHeaderNib = [UINib nibWithNibName: NSStringFromClass(YourHeaderView.class) bundle: nil];
    return sectionHeaderNib_;
}


- (YourHeaderView*) dequeueHeader
{
    return [self.sectionHeaders firstObjectPassingTest: ^(id obj) { return (BOOL) ([obj superview] == nil); }];
}


- (NSString*) sectionHeaderTitleForSection: (NSInteger) section
{
    return nil;
}


- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section
{
    YourHeaderView* headerView = [self dequeueHeader];
    if (!headerView)
    {
        headerView = [YourHeaderView instanceFromNib: self.sectionHeaderNib];
        [self.sectionHeaders addObject: headerView];
    }
    return headerView;
}

@end
Run Code Online (Sandbox Code Playgroud)