【问题标题】:UITableViewCell custom subclass view not updatedUITableViewCell 自定义子类视图未更新
【发布时间】:2025-12-27 22:35:07
【问题描述】:

在我的自定义表格视图单元子类中,文本标签之一的位置取决于 ivar (NSString) 的内容。 (即:如果 NSString 是空字符串,则 textlabel 框架的位置不同)。

位置更新如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    customOverlayCell *myCell = [self.tableView dequeueReusableCellWithIdentifier:@"CustomOverlayCell"];

    if ([buildingFName isEqual:@""])
    {
        CGRect titleLabelFrame = myCell.titleLabel.frame; 
        titleLabelFrame.origin.y  = 45;
        [myCell.titleLabel setFrame:titleLabelFrame];
    }

    return myCell;
}

我删除了部分不相关的代码。

结果是屏幕上出现的第一个单元格的布局正确更新,但向下滚动后出现的视图布局没有更新。

我没有正确使用 dequeueReusableCellWithIdentifier 吗?还是有什么问题?

编辑:

来自 EJV 的解决方案:

CGRect titleLabelFrame = myCell.titleLabel.frame; 

if ([buildingFName isEqual:@""])
{
    titleLabelFrame.origin.y  = 45;
} else {
    titleLabelFrame.origin.y  = 37;
}

[myCell.titleLabel setFrame:titleLabelFrame];

【问题讨论】:

    标签: iphone ios uitableview


    【解决方案1】:

    如果标题标签的框架是动态的,那么当您从表格视图中取出一个单元格时,该框架可能处于两种状态中的任何一种(当 buildingFName 为空时以及当它有字符时)。您需要确保在 buildingFName 不为空时设置框架。这样,标题标签的框架将始终正确设置。所以,你需要这样的代码:

    CGRect titleLabelFrame = myCell.titleLabel.frame;
    
    if ([buildingFName isEqual:@""])
    { 
        titleLabelFrame.origin.y  = 45;
    } else {
        // Change titleLabelFrame
    }
    
    [myCell.titleLabel setFrame:titleLabelFrame];
    

    【讨论】:

    • 工作就像一个魅力。我的编程太糟糕了。谢谢。
    【解决方案2】:

    恐怕,它需要对单元格进行子类化并实现 [UITableViewCell layoutSubviews] 以正确布置单元格的子视图。这就是我为切换表视图单元格做类似事情的方式:

    - (void)layoutSubviews
    {
        CGFloat const ESCFieldPadding = 10.0f;
    
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationBeginsFromCurrentState:YES];
    
        // call super layout
        [super layoutSubviews];
    
        // obtain widths of elements
        CGFloat contentWidth = self.contentView.frame.size.width;
        CGFloat contentHeight = self.contentView.frame.size.height;
        CGFloat switchWidth = self.switchView.frame.size.width;
        CGFloat switchHeight = self.switchView.frame.size.height;
        CGFloat labelWidth = contentWidth - (4 * ESCFieldPadding) - switchWidth;
    
        // correctly position both views
        self.textLabel.frame = CGRectMake(ESCFieldPadding, 0.0f, 
                                          labelWidth, contentHeight);
        // it is needed to explicitly resize font as for some strange reason,
        // uikit will upsize the font after relayout
        self.textLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
    
        CGRect switchFrame = self.switchView.frame;
        switchFrame.origin = CGPointMake(contentWidth - ESCFieldPadding - switchWidth,
                                         (contentHeight / 2) - (switchHeight / 2));
        self.switchView.frame = CGRectIntegral(switchFrame);
    
        [UIView commitAnimations];
    }
    

    【讨论】:

    • 我尝试将我的布局修改放入 - (void)layoutSubviews,但它没有改变任何东西。幸运的是,EJV 找到了答案。感谢您的帮助!
    【解决方案3】:

    尝试从您的单元格中禁用自动布局

    【讨论】:

    • 谢谢,但这个问题似乎在一年前就已经解决了!