我是新手。我正在使用此代码创建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;
}
答案 0 :(得分: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,因此请务必查看此代码以查找所需的引用计数。
答案 1 :(得分: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的答案,我唯一要改变的是只为单元格中的每个视图添加一个“tag”属性,这样您就不必每次都想要查找它。
还取出[[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];
答案 2 :(得分:0)
dequeReusablecellWithIdentifier:
方法获取返回已创建的单元格实例 ,如果引用仍指向nil,我们需要一个有效的单元格并创建一个单元格从{{1}返回} {方法。这是cellForRowatIndexpath:
中正在检查的内容。当您创建新单元格时,它是创建,因此所有设置都是自定义的,所有这些都必须在此处完成。