无法在UITableViewCell中更新UI对象的框架

时间:2012-10-13 12:12:06

标签: iphone objective-c uitableview

我有一个子类UITableViewCell。

我需要动态更改UILabel的框架。

这就是我所做的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"messageCell";
    MessageCell *cell = (MessageCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.Content.Text = @"Content!";
    [cell.Content setFrame:CGRectMake(0, 0, 10, 10)];
}

UILabel的文本确实发生了变化,因此这不是IBOutlet问题。 然而,框架保持与IB中定义的相同。

我以前做过这样的事情,所以我不确定这里出了什么问题......

感谢您的帮助。

修改

我用

[self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil]
     forCellReuseIdentifier:@"MessageCell"]; 

在viewDidLoad

6 个答案:

答案 0 :(得分:5)

在发布赏金后的几天我找到了答案,我希望有一天能帮到某人......

我不是百分之百确定原因,但我试图做的事情根本无法完成:

如果您通过Interface Builder进行了对象,则无法更改该对象的框架。

要进行我想要做的更改,我只是在子类中以“initWithCoder”编程方式创建这些对象。

content = [[UILabel alloc] initWithFrame:CGRectMake(120, 100, 200, 50)];
content.opaque = NO;
content.numberOfLines = 0;
[self.contentView addSubview:content];

然后我可以更改“ - (void)layoutSubviews”中的帧(但基本上我想要的任何地方)

- (void)layoutSubviews
{
    [super layoutSubviews];
    [cell.Content setFrame:CGRectMake(0, 0, 10, 10)];

    ...

答案 1 :(得分:2)

那里肯定有问题。

尝试 进行测试 以实现此目的:

tableView:willDisplayCell:forRowAtIndexPath:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell    forRowAtIndexPath:(NSIndexPath *)indexPath
{
    MessageCell* aCell = (MessageCell*)cell;
    aCell.Content.Text = @"Content!";
    [aCell.Content setFrame:CGRectMake(0, 0, 10, 10)];
}

结果是什么?

答案 2 :(得分:2)

如果启用了Autolayout,则无法编辑通过xib创建的UI对象框架。 有两种方法可以做到这一点:

  1. 禁用该xib的Autolayout。
  2. OR

    1. 为特定的NSlayout约束创建一个IBOutlet,并相应地附加它,并通过代码更新其常量属性值,并且不要忘记在实现constarint的对象上调用layOutIfNeeded或按照实现进行superview。

答案 3 :(得分:1)

将子视图添加到cell.Content并调整该​​子视图的大小而不是内容本身。单元格将始终被拉伸以适合您的表格视图,因此您不能将其缩小 (当然,要使单元格高度更小,只需应用tableView:heightForRowAtIndexPath:

答案 4 :(得分:1)

这可能与重用细胞的事实有关。试试这个

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"messageCell";
        MessageCell *cell = (MessageCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    if(cell == nil)
       { 
        cell = [[[MessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease];
        }
        cell.Content.Text = @"Content!";
        [cell.Content setFrame:CGRectMake(0, 0, 10, 10)];
        return cell;
    }

答案 5 :(得分:1)

您是否考虑覆盖自定义单元格中的- (void) layoutSubviews方法(即MessageCell)并在其中布置您的内容?我认为这是放置布局更改代码的最安全的地方,因为在其他地方它可能没有任何影响。不要忘记在[super layoutSubviews];的实施中致电layoutSubviews

考虑采用这种方法,让我们知道它是否适合您! 但是你需要考虑这种方法对性能的影响,因为每次表滚动时都会调用layoutSubviews

编辑:

layoutSubviews内为您的标签提供合适的框架尺寸,请考虑使用- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode进行框架计算。