UITableview dequeueReusableCellWithIdentifier和滚动冻结问题

时间:2011-08-03 22:13:23

标签: iphone ios objective-c xcode uitableview

所以我的tableview存在一些问题。我有一个自定义label,我将tableview cell放入UItableviewcell以添加比标准cells更好的图形。但是,我遇到了第一个问题,

  1. 我在cells上的文字标签在滚动时互相改写,只有当dequeueReusableCellWithIdentifier:移出屏幕然后又回来时。经过一些研究,我发现它可能与table有关,所以我调整了我的代码。这就是问题二出现的地方。

  2. 当我加载scroll时,所有内容都在正确的位置,正确看待所有内容。然而,当我开始- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"Run"); CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; static NSString *CellIdentifier = @"Cell"; UILabel *label; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; NSArray *keys = [[appDelegate rowersDataStore] allKeys]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; // Configure the cell... label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 15, cell.bounds.size.width - 10, 30)] autorelease]; label.font = [UIFont boldSystemFontOfSize:16]; label.backgroundColor = [UIColor clearColor]; label.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5]; label.shadowOffset = CGSizeMake(0,1); label.textColor = [UIColor colorWithRed:0x4c/255.0 green:0x4e/255.0 blue:0x48/255.0 alpha:1.0]; switch (indexPath.section) { case 0: label.frame = CGRectMake(0, 15, cell.bounds.size.width - 10, 30); label.textAlignment = UITextAlignmentCenter; break; case 1: label.textAlignment = UITextAlignmentLeft; UIImage *accessoryImage = [UIImage imageNamed:@"content_arrow.png"]; UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessoryImage]; cell.accessoryView = accessoryView; [accessoryView release]; break; } UIImageView *imgView = [[UIImageView alloc] initWithFrame:cell.frame]; UIImage* img = [UIImage imageNamed:@"odd_slice.png"]; imgView.image = img; cell.backgroundView = imgView; [imgView release]; //Selected State UIImage *selectionBackground = [UIImage imageNamed:@"row_selected.png"]; UIImageView *selectionView = [[UIImageView alloc] initWithFrame:cell.frame]; selectionView.image = selectionBackground; cell.selectedBackgroundView = selectionView; [selectionView release]; } switch (indexPath.section) { case 0: [label setText:@"Click to add new rower"]; break; case 1: [label setText:[[[appDelegate rowersDataStore] objectForKey:[keys objectAtIndex:indexPath.row]] objectForKey:@"Name"]]; break; } //Adds Text [cell addSubview:label]; return cell; 时,我可以到达除了最后一个细胞之外的所有细胞,它将进入第8个细胞的最底层并冻结,但我应该加载9个细胞。

  3. 我很困惑其中一些,有人可以提供一些代码或指导来帮助我吗?

    感谢。

    {{1}}

    }

1 个答案:

答案 0 :(得分:4)

我在这里看到几个问题。首先,这种方法的一般结构应该是......

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    // Attempt to dequeue the cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // If cell does not exist, create it, otherwise customize existing cell for this row
    if (cell == nil) {
        // Create cell
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        // Configure cell:
        // *** This section should configure the cell to a state independent of 
        //  whatever row or section the cell is in, since it is only executed 
        //  once when the cell is first created.
    }

    // Customize cell:
    // *** This section should customize the cell depending on what row or section 
    //  is passed in indexPath, since this is executed every time this delegate method
    //  is called.

    return cell;
}

基本上,UITableView使用单个UITableViewCell实例绘制表格视图中的每个单元格。因此,当您首次创建此单元格时,应将其配置为将使用此实例的所有单元格共有的状态,而与indexPath中传递的任何行或节无关。在您的示例中,这涉及创建标签,图像和背景图像实例,并将它们作为子视图添加到单元格中。

创建单元格后(也就是if (cell == nil)语句之外),您应该根据单元格查找indexPath中包含的特定行和部分的方式来自定义其属性。由于您要在代码的这一部分中访问自定义标签,因此我为其分配了tag值,以便我们可以在使用viewWithTag:创建它的代码段之外访问它。一旦我们有了标签,我们就可以根据部分进行自定义,也可以做任何我们想要的事情,例如自定义配件视图。

我稍微修改/清理了下面的代码。到目前为止,这不是最有效或最优雅的方式来做你想做的事情,但我试图保留尽可能多的代码。我没有对此进行过测试,但是如果你尝试它应该可以工作:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Run");
    CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    NSArray *keys = [[appDelegate rowersDataStore] allKeys];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        // Configure the cell...

        UILabel *label;
        label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 15, cell.bounds.size.width - 10, 30)] autorelease];
        label.font = [UIFont boldSystemFontOfSize:16];
        label.opaque = NO;
        label.backgroundColor = [UIColor clearColor];
        label.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5];
        label.shadowOffset = CGSizeMake(0,1);
        label.textColor = [UIColor colorWithRed:0x4c/255.0 green:0x4e/255.0 blue:0x48/255.0 alpha:1.0];
        label.tag = 100;
        [cell addSubview:label];
        [label release];

        UIImageView *imgView = [[UIImageView alloc] initWithFrame:cell.frame];
        UIImage* img = [UIImage imageNamed:@"odd_slice.png"];
        imgView.image = img;
        cell.backgroundView = imgView;
        [imgView release];

        //Selected State
        UIImage *selectionBackground = [UIImage imageNamed:@"row_selected.png"];
        UIImageView *selectionView = [[UIImageView alloc] initWithFrame:cell.frame];
        selectionView.image = selectionBackground;
        cell.selectedBackgroundView = selectionView;
        [selectionView release];
    }

    UILabel *lbl = (UILabel *)[cell viewWithTag:100];
    switch (indexPath.section) {
        case 0:
            cell.accessoryView = nil;

            lbl.frame = CGRectMake(0, 15, cell.bounds.size.width - 10, 30);
            lbl.textAlignment = UITextAlignmentCenter;
            [label setText:@"Click to add new rower"];
            break;
        case 1:
            UIImage *accessoryImage = [UIImage imageNamed:@"content_arrow.png"];
            UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessoryImage];
            cell.accessoryView = accessoryView;
            [accessoryView release];

            lbl.frame = CGRectMake(20, 15, cell.bounds.size.width - 10, 30);
            lbl.textAlignment = UITextAlignmentLeft;
            [lbl setText:[[[appDelegate rowersDataStore] objectForKey:[keys objectAtIndex:indexPath.row]] objectForKey:@"Name"]];
            break;
    }

    return cell;
}