【问题标题】:Cannot update UI object's frame in UITableViewCell无法在 UITableViewCell 中更新 UI 对象的框架
【发布时间】:2012-10-13 12:12:05
【问题描述】:

我有一个子类 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 中

【问题讨论】:

    标签: iphone objective-c uitableview


    【解决方案1】:

    在发布赏金几天后,我找到了答案,我希望有一天这会对某人有所帮助......

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

    如果您通过 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)];
    
        ...
    

    【讨论】:

      【解决方案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)];
      }
      

      结果如何?

      【讨论】:

      • 伟大的丹尼尔它对我有用。最后你给出了一个非常知名的问题的解决方案。
      【解决方案3】:

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

      1. 禁用该 xib 的自动布局。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 我没有尝试编辑单元格的视图,而是该单元格内的 UILabel。
        【解决方案5】:

        这可能与重复使用单元格有关。试试这个

          - (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;
            }
        

        【讨论】:

        • 你设置了tableview的数据源了吗?您所说的应用程序未到达(cell == nil)是什么意思,是否调用了 cellForRowAtIndexPath?
        • 那么你在哪里分配你的单元格?
        • 它是从情节提要中加载的
        • 我使用 [self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil] forCellReuseIdentifier:@"MessageCell"];
        【解决方案6】:

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

        考虑采用这种方法,如果它适合您,请告诉我们! 但是您需要考虑这种方法对性能的影响,因为每次表格滚动时都会调用layoutSubviews

        编辑:

        为适应layoutSubviews 内标签的正确帧大小,请考虑使用- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode 进行帧计算。

        【讨论】:

        • 仍然没有得到任何结果...我确保正在调用 MessageCell 中覆盖的 layoutSubviews,并且我还调用了超级函数
        • 另一个非常尴尬的尝试:覆盖 MessageCell.m 中的“- (void) setFrame: (CGRect) frame” 方法(再次调用 super)并在其中放置一个 NSLog 语句以查看它何时在表视图重绘周期中调用!
        • 关于我最初回答的另一个问题:在您覆盖的“layoutSubviews”方法中,您何时调用“[super layoutSubviews]”?尝试在为标签设置框架之后调用 super。
        • 尝试在之前和之后拨打电话。如果我之前放过,我刚刚注意到如果我调用 [self.tableview reloadData],单元格会更新。但不是在滚动时
        • 我遇到了一个非常相似的问题。我几乎通过在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中以编程方式创建 UILabel 并添加 [cell addSubview:myLabel]; 来解决它。 - 但我在滚动时出现了重复的 uilabel
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多