添加到自定义部分标题视图的按钮在删除行时消失

Posted

技术标签:

【中文标题】添加到自定义部分标题视图的按钮在删除行时消失【英文标题】:Button added to custom section header view disappears when row is deleted 【发布时间】:2010-12-16 17:10:35 【问题描述】:

刚刚在我的应用程序中遇到了一些非常奇怪的行为。我在最简单的情况下重现了这个问题:

NSMutableArray *data;

- (void)viewDidLoad 
    [super viewDidLoad];
    data = [[NSMutableArray arrayWithObjects:@"1", @"2", @"3", nil] retain];


- (UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section  
    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, 32.0)];
    header.backgroundColor = [UIColor lightGrayColor];
    [header addSubview:self.button];
    return header;


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
    if (editingStyle == UITableViewCellEditingStyleDelete)     
        [data removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
    


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    return data.count;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
    cell.textLabel.text = [data objectAtIndex:indexPath.row];
    return cell;


- (void)dealloc 
    [super dealloc];

每次我删除一行;我标题中的按钮消失了!无论我使用哪种类型的 rowAnimation,都会发生这种情况。如果我向上滚动表格以使标题滚动;当标题返回时,按钮返回。该按钮在 xib 文件中创建。

我可以通过以下两种方式之一解决它:

删除后重新加载tableView数据;有一个延迟,以便删除动画首先完成。

在 viewForHeaderInSection 中而不是在 interfaceBuilder 中创建按钮。

我真的很想了解这里发生了什么。按钮去哪儿了?我已经确认删除一行时会调用 viewForHeaderInSection。

编辑我尝试更改它,以便在 viewForHeader 中创建按钮,而不是在 xib 中,但它会导致其他奇怪的问题......当我创建或删除按钮时,我正在设置某些属性,如标题和启用取决于表中有多少项目。当我删除表格中的最后一行时,在我将按钮从屏幕上滚动并重新打开之前,我看不到文本中的更新和启用状态。

【问题讨论】:

【参考方案1】:

因为您的按钮只有一个实例,所以如果表格视图决定创建一个新的标题视图,那么该按钮将从其当前父级中移除并移至新的父级。即使您的表格中只有一个部分,表格视图也可能在内部做一些奇怪的事情并在屏幕外重新创建标题视图,因此您不能依赖任何时候只存在一个。

应该viewForHeaderInSection: 中创建按钮并解决其他问题。而不是只更新 viewForHeaderInSection 中的按钮属性,您应该处理任何删除事件,以便删除一行也会更新按钮。

【讨论】:

我认为您可能正在做某事......也许我正在操作的按钮被添加到我的标题视图的其他实例中;一个没有显示的。不过,我正在更新我的删除方法中的标题;不仅当我在 viewForHeaderInSection 中创建按钮时。如果我每次调用 viewForHeaderInSection 时都创建新按钮;似乎我应该看到新按钮(在新标题中)或上一个按钮(因为新标题尚未显示)。但是按钮的两个实例此时都应该有正确的标题......【参考方案2】:

委托方法tableView:heightForHeaderInSection: 的实现在哪里?这是tableView:viewForHeaderInSection: 正常工作所必需的。检查文档。 Reference for UITableView delegate

我已经确认 viewForHeaderInSection 在什么时候被调用 我删除了一行。

您是否确认为带有添加按钮的特定标题调用 viewForHeaderInSection? 然后,尝试添加

[header bringSubviewToFront:self.button];  

添加按钮后。

【讨论】:

另外,你有什么理由不重用 tableView:cellForRowAtIndexPath 中的表格单元格? 我在我的实际代码中重用表格单元格;为了在此处发布代码,我使其尽可能简洁,同时仍然发布具有相同问题的代码。我在 xib 文件中定义 heightForHeader。 我的表中只有 1 个部分。我注意到每次加载或刷新表时都会调用 viewForHeaderInSection 两次......两次都通过了 section:0。不确定这是否相关。我尝试添加bringSubviewToFront;同样的问题。 (调用 addSubview 应该把它放在前面......)【参考方案3】:

好吧,我至少设法解决了我的问题...我为我在viewForheaderAtSection 中创建的视图创建了一个 iVar 和属性,然后如果我还没有一个新视图,我只会创建一个新视图。否则我只返回我已经拥有的标题;像这样:

- (UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section  
    if (!self.myHeader)
        UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, 32.0)];
        header.backgroundColor = [UIColor lightGrayColor];
        [header addSubview:self.button];
        self.myHeader = header;
        [header release];
    
    return self.myHeader;

这行得通,但了解到底发生了什么仍然很棒。据我所知,系统正在调用 viewForHeaderInSection,但是我在该方法中返回的视图实例实际上并没有被使用/显示;至少直到我做了一些导致视图重绘的事情......

【讨论】:

以上是关于添加到自定义部分标题视图的按钮在删除行时消失的主要内容,如果未能解决你的问题,请参考以下文章

将子视图添加到自定义 viewForHeaderInSection 会中断 VoiceOver 导航

将多个自定义栏按钮添加到自定义导航栏

自定义视图上的 AirPlay 按钮

如何将子视图添加到自定义 UICollectionViewCell

将子视图添加到自定义类

Woocommerce 添加到自定义产品的购物车按钮