UITableView披露指标疯狂

时间:2011-11-30 23:39:36

标签: iphone ios uitableview uinavigationcontroller

我有一个UITableView(在UIViewController上),它是通过navigationController推送的。随着推动,我选择我想要填充表格的数组。推送代码是这样的:

if(self.newView == nil)
{
    NewView *viewTwo = [[NewView alloc] initWithNibName:@"Bundle" bundle:[NSBundle mainBundle]];
    self.newView = viewTwo;
    [viewTwo release];
}

[self.navigationController pushViewController:self.newView animated:YES];
newView.tableArray=newView.arrayWithOptionOne;
[newView.tableView reloadData];

一切正常,每次都会重新加载表格。然而,在第0部分的最后一行中,有一个加载部分1的开关。 第1部分的最后一行是tappable(didSelect ...),它加载了一个modalView。在最后一根杆子上,我添加了一个披露指示器,并在敲击时添加了蓝色背景。该表有滑块,标签等。所以定制很长:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell *cell = nil;


static NSString *kDisplayCell_ID = @"DisplayCellID";

cell = [tableView dequeueReusableCellWithIdentifier:kDisplayCell_ID];

if (cell == nil)
    {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kDisplayCell_ID] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    }
else
    {

    UIView *viewToRemove = nil;
    viewToRemove = [cell.contentView viewWithTag:1];
    if (viewToRemove)
        [viewToRemove removeFromSuperview];

    UIView *viewToRemove2 = nil;
    viewToRemove2 = [cell.contentView viewWithTag:2];
    if (viewToRemove2)
        [viewToRemove2 removeFromSuperview];


 }


    if (indexPath.section==0) {
        UIControl *cellValueS = [[[arrayTable objectAtIndex:indexPath.section] objectForKey:kViewKey] objectAtIndex:indexPath.row];
        [cell.contentView addSubview:cellValueS];
    }

    if (indexPath.section==0 && indexPath.row==3) {
        UIControl *cellValueL = [[[arrayTable objectAtIndex:indexPath.section] objectForKey:kViewLabel] objectAtIndex:0] ;
        [cell.contentView addSubview:cellValueL];
    }

    if (indexPath.section==1 && indexPath.row==0){
        UIControl *cellValueS = [[[arrayTable objectAtIndex:indexPath.section] objectForKey:kViewKey] objectAtIndex:indexPath.row] ;
        [cell.contentView addSubview:cellValueS];
    } 

    if (indexPath.section==1 && indexPath.row==1) {
        UIControl *cellValueS = [[[arrayTable objectAtIndex:indexPath.section] objectForKey:kViewKey] objectAtIndex:indexPath.row] ;
        [cell.contentView addSubview:cellValueS];

        UIControl *cellValueL = [[[arrayTable objectAtIndex:indexPath.section] objectForKey:kViewLabel] objectAtIndex:0] ;
        [cell.contentView addSubview:cellValueL];
    }

    if (indexPath.section==1 && indexPath.row==2) {
        cell.selectionStyle = UITableViewCellSelectionStyleBlue;
        cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
    }

    return cell;
}

到目前为止还可以。

问题是,当我回到上一个视图并选择另一个选项来填充表格时,再次按下它时,我会在同一部分的其他行上看到披露指示符和蓝色选择背景。我观察到它取决于滚动表的位置。

我试图理解为什么会这样,但我不能。我已经以某种方式解决了这个问题,方法是将newView设置为nil并释放它,然后在再次推送之前再次分配它。

我在这里做错了吗?或者为什么披露指标和窃听背景出现在它们不应该出现的地方?

提前致谢!

开关的动作

-(void)extraOptionsSwitchAction:(id)sender{



 switch(extraOptionsSwitch.isOn) {

 case 1:

 // [self.tableView beginUpdates];
 [self.tableView insertSections: [NSIndexSet indexSetWithIndex:1]  withRowAnimation:UITableViewRowAnimationAutomatic];
 [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];

 //[self.tableView reloadData];
 //  [self.tableView endUpdates];

 break;

 case !1:

 //   [self.tableView beginUpdates];
 [self.tableView deleteSections: [NSIndexSet indexSetWithIndex:1]  withRowAnimation:UITableViewRowAnimationAutomatic];
 // [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];

 [self.tableView reloadData];
 // [self.tableView endUpdates];

 break;

 }
 }

2 个答案:

答案 0 :(得分:2)

必须重复使用细胞。您可能不会在细胞创建方法中区分不同的细胞类型 - 因此一个离开屏幕的细胞可以很容易地重复用于另一个(不同类型)细胞。此外,您似乎反复添加子视图 - 只在实例化单元格(使用alloc / int)时执行此操作,而不是在配置时执行。

此外,对于不同的细胞类型,请使用不同的标识符(您没有显示此代码)。

编程指南在表视图及其单元和重用模式方面有很好的例子。它值得阅读几次 - 它很容易出错,是性能调优的主要话题。

修改

现在您添加了更多代码,似乎还有另一个问题:

if (indexPath.section==1 && indexPath.row==2) {
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}

您错过了else部分。 selectionStyleaccessoryType设置为之前设置的值 - 您错过了为所有其他单元格正确配置单元格。

每个单元格类型应该真正获得自己的标识符。如果从该代码中很难判断添加/删除子视图是否按预期工作。

有一种想法:因为你不是真的在这里重复使用了很多单元格,你甚至可以通过改变来禁用重用

static NSString *kDisplayCell_ID = @"DisplayCellID";
cell = [tableView dequeueReusableCellWithIdentifier:kDisplayCell_ID];

static NSString *kDisplayCell_ID = nil;

这将始终产生一个新的细胞。不过,我不会在一般情况下推荐这个。

答案 1 :(得分:0)

这是由cellReusability引起的,长期以来,它浪费了很多开发人员的时间和精力。如果您知道单元格可重用性的概念,您会知道在滚动时,行和节的索引保持不变(尽管您希望uiTableView上的不同位置的索引不同。)

唯一的方法是subClass UITableViewCell并创建您自己的CustomUITableViewCell,并使用披露指示器实现该功能,或者仅针对适合屏幕的小型TableView进行输入并制作scrollable = NO