0

我是新手。我正在使用此代码创建一个UITableViewCell,但是当我重新加载表格时,按钮的图像并不总是正确的,尽管所有标签都可以正常工作。我不知道为什么。我该如何解决这个问题?

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

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];

        UILabel *FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
        FileNameLabel.tag = 1000;
        FileNameLabel.backgroundColor = [UIColor clearColor];
        FileNameLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
        FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
        FileNameLabel.textColor = [UIColor blackColor];
        [cell.contentView addSubview: FileNameLabel];
        [FileNameLabel release];


        UILabel *UploadTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 150, 25)];
        UploadTimeLabel.tag = 2000;
        UploadTimeLabel.backgroundColor = [UIColor clearColor];
        UploadTimeLabel.font = [UIFont fontWithName:@"Helvetica" size:12];
        UploadTimeLabel.textColor = [UIColor grayColor];
        [cell.contentView addSubview: UploadTimeLabel];
        [UploadTimeLabel release];


        UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];
        pricelabel.backgroundColor = [UIColor clearColor];
        pricelabel.font = [UIFont fontWithName:@"Helvetica" size:16];
        pricelabel.font = [UIFont boldSystemFontOfSize:16];
        pricelabel.textColor = [UIColor darkGrayColor];
        pricelabel.tag = 3000;
        //pricelabel.hidden = YES;
        pricelabel.textAlignment = NSTextAlignmentRight;
        [cell.contentView addSubview: pricelabel];
        [pricelabel release];


        market = [[UIButton alloc] init];;
        [market setFrame:CGRectMake(200, 6, 30, 30)];
         market.tag = 4000;

        [market addTarget:self action:@selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];


        [cell.contentView addSubview:market];
   }

    if( [temp count] > 0)
    {
        UILabel *fileNameLbl = (UILabel*)[cell.contentView viewWithTag:1000];
        fileNameLbl.text =[temp objectAtIndex:indexPath.row];

        UILabel *uploadlbl = (UILabel*)[cell.contentView viewWithTag:2000];
        uploadlbl.text =[UploadTimeAllArr objectAtIndex:indexPath.row];
    }

    UIButton *marketButton = (UIButton*)[cell.contentView viewWithTag:4000];
    [marketButton setTag:indexPath.row];
    if([sellingArray count]>0)
    {
        NSLog(@"sellingArray %@",sellingArray);
        if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:@"0"]) // nothing
        {

            [marketButton setSelected:NO];
            [marketButton setImage:[UIImage imageNamed:@"Marketplace.png"] forState:UIControlStateNormal];
            marketButton.enabled = YES;

        }
        else if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:@"2"])  // marketplace
        {

            [marketButton setSelected:YES];
            [marketButton setImage:[UIImage imageNamed:@"MarketplaceSelect.png"] forState:UIControlStateNormal];
            marketButton.enabled = YES;

        }
    }


    return cell;
}
4

3 回答 3

1

您的主要问题是每次调用此方法时您都在单元格中重新创建新视图。你想在里面创建所有可重用的元素,if(cell == nil)否则它会重复。任何动态的东西都必须在此之外创建。我拿走了你的代码并修改了它。这应该会更好。

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        // Everything that does not change should go in here!

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];


        pricelabel.backgroundColor = [UIColor clearColor];
        pricelabel.font = [UIFont fontWithName:@"Helvetica" size:16];
        pricelabel.font = [UIFont boldSystemFontOfSize:16];
        pricelabel.textColor = [UIColor darkGrayColor];
        pricelabel.tag = 3000;
        //pricelabel.hidden = YES;
        pricelabel.textAlignment = NSTextAlignmentRight;
        [cell addSubview:pricelabel];

        UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
        [market setFrame:CGRectMake(200, 6, 30, 30)];
        [market addTarget:self action:@selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
        [cell addSubview:market];
    }

    // find market button, since we could be reusing a cell we cannot rely on a tag
    // value to find it. (This would only work with one button though).
    UIButton *market;
    for (UIView *subview in cell.subviews) {
    if ([subview isKindOfClass:[UIButton class]]) {
            market = (UIButton *)subview;
            break;
        }
    }

    // set all defaults in case of reuse
    [market setImage:[UIImage imageNamed:@"DefaultImage.png"] forState:UIControlStateNormal];
    market.selected = YES;
    market.enabled = NO;
    market.clearsContextBeforeDrawing = NO;

    if([sellingArray count] > 0) {
        NSLog(@"sellingArray %@",sellingArray);
        if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:@"0"]) {
            // not sure if this is supposed to be YES or NO
            market.clearsContextBeforeDrawing = YES;
            [market setSelected:NO];
            [market setImage:[UIImage imageNamed:@"Marketplace.png"] forState:UIControlStateNormal];
            market.enabled = YES;
        }
    }
    [market setTag:indexPath.row];

    return cell;
}

由于您似乎没有使用 ARC,因此请确保查看此代码以获取任何需要的引用计数。

于 2013-08-19T15:51:42.063 回答
0

dequeReusablecellWithIdentifier:方法获取返回已经创建的单元格实例可用cellForRowatIndexpath:,如果参考点仍然为零,我们需要一个有效的单元格并创建一个从该方法返回的单元格。这就是在中检查的内容(cell ==nil)。当您创建一个新单元格时,它正在创建因此所有自定义设置都必须在这里完成。

于 2013-08-20T14:43:08.510 回答
0

第二次编辑:

这是从上面的答案中复制的:

方法内部-cellForRowAtIndexPath:

    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellSubtitle];
        UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
            [market setFrame:CGRectMake(200, 6, 30, 30)];
        [market addTarget:self action:@selector(marketPressedAction:)     forControlEvents:UIControlEventTouchDown];

        [cell.contentView addSubview:market];

    //Add all your UILabel INITIATION stuff here as well

    }

    UIButton *marketButton;
    for (UIView *subview in cell.subviews) {    
        if ([subview isKindOfClass:[UIButton class]]) {
            marketButton = (UIButton *)subview;
            break;        
        }    
    }
    marketButton.tag = [indexPath row];

    UILabel *priceLabel = [cell.contentView viewWithTag:3000];
    UILabel *uploadTimeLabel = [cell.contentView viewWithTag:2000];

    //Set up your labels and button now

    return cell;
}


    EDIT: Leaving my original answer below for posterity but I see that you are setting the table index row as the MarketButton's tag. If you're using that to figure out which dataSource object to query, this is bad practice. You should be making a custom cell which can hold a reference to the object in your data source, so you don't have to ask the button for its tag, and then ask the data source array for the object at index:tag. 

这不好的原因是因为在某个地方,您的数组的状态可能会改变,但表格单元格仍然显示并且仍然包含指向错误索引的标记。如果您只是让单元格跟踪有问题的对象,那么无论数组结构发生什么情况,您都可以保证修改您需要的对象。

关于 Firo 的答案,我唯一要改变的就是在单元格中的每个视图中添加一个“标签”属性,这样您就不必每次想要找到它时都进行迭代。

也去掉了这[[UIButton alloc]init]条线,因为它是多余的,可能被认为是一个悬空指针。

if (cell == nil) {
    // Everything that does not change should go in here!

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
    [market setFrame:CGRectMake(200, 6, 30, 30)];
    [market addTarget:self action:@selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];

    market.tag = 9999;

    [cell.contentView addSubview:market];
}

//don't have to do UIView iteration here
UIButton *marketButton = [cell.contentView viewWithTag:9999];
于 2013-08-19T16:04:51.513 回答