何时从UITableViewCell中删除子视图?

时间:2014-03-11 13:44:25

标签: ios objective-c uitableview uisearchbar

我有UITableView searchBarsearchDisplayController。我想要做的是在没有找到结果时显示button。因此用户可以搜索服务器的数据库。我有NSMutableArray来存储searchResults。所以我的委托方法如下所示:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titulo contains [cd] %@", searchText];
    NSArray *filtroUsuario = [self.objects filteredArrayUsingPredicate:predicate];
    self.searchResults = [[NSMutableArray alloc] initWithArray:filtroUsuario];
    if (self.searchResults.count < 1) {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        btn.frame = CGRectMake(0, 0, 320, 50);
        btn.showsTouchWhenHighlighted = YES;
        [btn setTitle:@"Procurar no Banco de Dados" forState:UIControlStateNormal];
        btn.tag = 1;
        [self.searchResults addObject:btn];
        self.adicionar = YES;
    }
}

基本上,如果没有结果,我会在结果button中创建并添加array。然后,在cellForRowAtIndexPath中,我有以下内容:

if (tableView == self.searchDisplayController.searchResultsTableView) {
        if (self.adicionar == YES) {
            cell.textLabel.text = @"";
            [cell.contentView addSubview:self.searchResults[indexPath.row]];
            self.adicionar = NO;
        }

这会完全按我想要的方式显示button,按下cancelButton或问题button时,我只是将其从searchResults中删除,以防用户再次搜索。 [self.searchResults removeAllObjects]

问题在于,由于我正在重复使用单元格,当用户再次搜索时,subview仍然存在。我有几个选项来处理这个问题,我可以为单元格创建一个属性,并在按下button时删除子视图。但我选择在[[cell.contentView viewWithTag:1] removeFromSuperview];的开头添加行cellForRowAtIndexPath,因此当再次调用时,它会在继续之前删除subViews

现在一切都很完美。我的问题是,这是最好的方法还是更简单的方法。由于我的应用程序是一个复杂的应用程序,我非常关注内存和性能,此外,我真的想学习最酷的技术。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

在UITableViewCell上查看-prepareForReuse。可能最适合您描述的确切情况。 (下面的草图示例)

@interface CustomCellName : UITableViewCell
@property (strong, nonatomic) UIButton *someButton;
@end

@implementation
- (void)prepareForReuse
{
    _someButton.hidden = YES;
    //etc...
}
@end

标签也很好,尽管许多人发现这种方法令人不满意。 (*引用需要)

另一种方法是使用UIButton作为属性将UITableViewCell子类化,您可以通过-cellForRowAtIndexPath从tableView进行调整。

答案 1 :(得分:1)

最好是一个灵活的术语 - 在哪方面最好......

你有什么作品,但不是一个好的责任分配。最好创建一个自定义单元子类,并让它提供一个可以添加自定义按钮的API。单元格子类将处理prepareForReuse中按钮的清理。

从内存和性能的角度来看,差别不大。但是使用细胞亚类更正确。

为了提高性能,最好不要创建和销毁按钮实例。因此,对于您的单元子类来说,最好创建一个按钮,但在需要之前将其隐藏起来,然后显示它。现在,prepareForReuse只会隐藏按钮。通常这会平均使用更多的内存 - 这是一个权衡...

答案 2 :(得分:0)

首先,将控件与您的应用数据混合不是一个好习惯。您可以使它按现有的方式工作,但从长远来看,它可以将UI与应用程序数据分开。表视图应该完成呈现操作数据的数据和控件的所有工作,因此最好添加字符串&#34; No Data&#34;到你的结果数组,然后在cellForRowAtIndexPath中处理它。在您的单元格上创建一个按钮,只需在需要时隐藏/显示它。不要担心内存消耗,单元格可以重复使用,因此您将拥有非常少量的按钮(隐藏的按钮)。

第二件事,如果你真的不想创建一个按钮然后标记它,例如,当你决定需要它时创建它并标记为1000.然后当你重新加载并且不想显示它,只要问你的单元格是否有标签== 1000的视图并从superview中删除它。但是,如果你为每个可见细胞创建一个按钮,那么它就是一种矫枉过正,你的记忆完整性也不会受到威胁。