Ios 首次显示表格时未显示UITableViewCell子视图

Ios 首次显示表格时未显示UITableViewCell子视图,ios,uitableview,subview,addsubview,Ios,Uitableview,Subview,Addsubview,我试图在我的表格单元格中添加删除线标签(以布尔hasStrikethrough为条件)。问题是,删除线在第一次显示表时不会出现(即使hasStrikethrough==YES)。如果滚动表格,则会重新显示行并正确显示删除线。删除线只是作为UITableViewCell的子视图添加的UILabel 以下是我的CellForRowatineXpath代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtInde

我试图在我的表格单元格中添加删除线标签(以布尔hasStrikethrough为条件)。问题是,删除线在第一次显示表时不会出现(即使hasStrikethrough==YES)。如果滚动表格,则会重新显示行并正确显示删除线。删除线只是作为UITableViewCell的子视图添加的UILabel

以下是我的CellForRowatineXpath代码:

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

static NSString *CellIdentifier = @"ItemCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell==nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}


Item  *item = [self.fetchedResultsController objectAtIndexPath:indexPath];

cell.textLabel.text = item.itemName;
cell.textLabel.textAlignment = UITextAlignmentLeft;
cell.showsReorderControl = YES;
cell.shouldIndentWhileEditing = NO;

if ([[item hasStrikethrough] boolValue] == YES) {
    [self addStrikethrough:cell];
}

return cell;
}
以下是AddStreethrough的代码:

- (void)addStrikethrough:(UITableViewCell*)cell
{
CGRect frame = cell.textLabel.frame;
UILabel *strikethrough = [[UILabel alloc] initWithFrame:frame];
strikethrough.opaque = YES;
strikethrough.backgroundColor = [UIColor clearColor];
strikethrough.text = @"------------------------------------------------";
strikethrough.lineBreakMode = UILineBreakModeClip;
[cell addSubview:strikethrough];
}

提前感谢:-)

根据单元的重用标识符重用单元。目前,您只使用一个标识符,因此“无子视图的单元格”在操作系统中看起来与“有子视图的单元格”相同

尝试在开始时检查删除条件,并在这种情况下创建一个新的重用标识符(例如,
删除标识符

这里有一种方法可以实现我的建议:

Item *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
BOOL isStrike = ([[item hasStrikethrough] boolValue]);

static NSString *CellIdentifier = @"ItemCell";
static NSString *StrikeIdentifier = @"ItemCellStrike";

UITableViewCell *cell = (isStrike)
                        ? [tableView dequeueReusableCellWithIdentifier:StrikeIdentifier]
                        : [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell==nil) {
    if (isStrike) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:StrikeIdentifier];
        [self addStrikethrough:cell];
    } else {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
}

. . .

单元根据其重用标识符进行重用。目前,您只使用一个标识符,因此“无子视图的单元格”在操作系统中看起来与“有子视图的单元格”相同

尝试在开始时检查删除条件,并在这种情况下创建一个新的重用标识符(例如,
删除标识符

这里有一种方法可以实现我的建议:

Item *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
BOOL isStrike = ([[item hasStrikethrough] boolValue]);

static NSString *CellIdentifier = @"ItemCell";
static NSString *StrikeIdentifier = @"ItemCellStrike";

UITableViewCell *cell = (isStrike)
                        ? [tableView dequeueReusableCellWithIdentifier:StrikeIdentifier]
                        : [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell==nil) {
    if (isStrike) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:StrikeIdentifier];
        [self addStrikethrough:cell];
    } else {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
}

. . .

问题在于行
CGRect frame=cell.textLabel.frame
单元格的textLabel尚未布局,因此框架将为(0,0,0,0),而u将看不到删除线标签

你在下一个单元格中看到删除线的原因是因为这些单元格是重复使用的,它们已经放置了textLabel

在我看来,你有两个选择:
第一个选项,自己设置删除线框,你可以使用sizeWithFont来确定所需的宽度,字体应该是TextField字体。稍微玩一下,找到正确的x偏移量,这样它就会精确地显示在文本标签上

- (void)addStrikethrough:(UITableViewCell*)cell
{
    CGSize textLabelSize = [cell.textLabel.text sizeWithFont:[UIFont systemFontOfSize:20.0]];

    CGFloat cellHeight = cell.bounds.size.height;
    CGFloat strikethroughLabelHeight = 20.0;

    CGRect frame = CGRectMake(12, (cellHeight - strikethroughLabelHeight)/2, textLabelSize.width, strikethroughLabelHeight);
    UILabel *strikethrough = [[UILabel alloc] initWithFrame:frame];
    strikethrough.opaque = YES;
    strikethrough.backgroundColor = [UIColor clearColor];
    strikethrough.text = @"------------------------------------------------";
    strikethrough.lineBreakMode = UILineBreakModeClip;
    [cell.contentView addSubview:strikethrough];
}  
第二个选项是将UITableViewCell子类化,并向其添加删除线标签。

然后你可以在layoutSubviews方法中设置它的框架,你可以根据需要隐藏/取消隐藏此标签…

问题在于行
CGRect frame=cell.textLabel.frame
单元格的textLabel尚未布局,因此框架将为(0,0,0,0),而u将看不到删除线标签

你在下一个单元格中看到删除线的原因是因为这些单元格是重复使用的,它们已经放置了textLabel

在我看来,你有两个选择:
第一个选项,自己设置删除线框,你可以使用sizeWithFont来确定所需的宽度,字体应该是TextField字体。稍微玩一下,找到正确的x偏移量,这样它就会精确地显示在文本标签上

- (void)addStrikethrough:(UITableViewCell*)cell
{
    CGSize textLabelSize = [cell.textLabel.text sizeWithFont:[UIFont systemFontOfSize:20.0]];

    CGFloat cellHeight = cell.bounds.size.height;
    CGFloat strikethroughLabelHeight = 20.0;

    CGRect frame = CGRectMake(12, (cellHeight - strikethroughLabelHeight)/2, textLabelSize.width, strikethroughLabelHeight);
    UILabel *strikethrough = [[UILabel alloc] initWithFrame:frame];
    strikethrough.opaque = YES;
    strikethrough.backgroundColor = [UIColor clearColor];
    strikethrough.text = @"------------------------------------------------";
    strikethrough.lineBreakMode = UILineBreakModeClip;
    [cell.contentView addSubview:strikethrough];
}  
第二个选项是将UITableViewCell子类化,并向其添加删除线标签。

然后你可以在layoutSubviews方法中设置它的框架,你可以根据需要隐藏/取消隐藏此标签…

首先,我在CellForRowatineXpath中尝试了此方法:。我从addStrikethrough:中获取了代码,并将其放入添加到if(cell==nil)的else语句中。我已将else语句中的cell.textlab.text硬编码为等于“DEQUEUED cell”。我注释掉了addStreethrough的条件调用:。当你跑的时候。该表显示了文本为“出列单元格”但没有删除线的行?那么每一行都是一个出列单元,每一行都不能显示删除线?每个单元格都应该添加子视图。没有新的单元格被创建,所以不应该有标识符混淆。我在我的答案中添加了一个代码示例,试图说明我的意思。你需要模板单元格拥有显示其数据所需的一切,因为操作系统不会每次都要求你创建它。嗨,凯文,非常感谢你看这个。我已经实现了您提供的代码,但不幸的是,它不适合我。我还将isStrike硬编码为YES,以排除我的核心数据是错误的。当我再次运行时,单元格显示为无删除线。我已通过以确保调用AddStreethrough:。即使我滚动行,删除线也不会出现(我的代码是这样的)。你所做的看起来与我以前做的表相似…一个不同之处是我的单元格有自定义背景视图,我在其中设置了自动调整大小的掩码,例如,
newView.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight
cell.backgroundView=newView。我不确定这个细节是否重要。首先,我在cellForRowAtIndexPath中尝试了这个方法:。我从addStrikethrough:中获取了代码,并将其放入添加到if(cell==nil)的else语句中。我已将else语句中的cell.textlab.text硬编码为等于“DEQUEUED cell”。我注释掉了addStreethrough的条件调用:。当你跑的时候。该表显示了文本为“出列单元格”但没有删除线的行?那么每一行都是一个出列单元,每一行都不能显示删除线?每个单元格都应该添加子视图。没有新的单元格被创建,所以不应该有标识符混淆。我在我的答案中添加了一个代码示例,试图说明我的意思。你需要模板单元格拥有显示其数据所需的一切,因为操作系统不会每次都要求你创建它。嗨,凯文,非常感谢你看这个。我已经实现了您提供的代码,但不幸的是,它不适合我。我还将isStrike硬编码为YES,以排除我的核心数据是错误的。当我再次运行时,单元格显示为无删除线。我已通过以确保调用AddStreethrough:。即使我滚动行,删除线也不会移动