iPhone TableViewCell 动态高度崩溃

发布于 2024-09-14 10:01:34 字数 3621 浏览 4 评论 0原文

我一直在尝试创建一个由第一行中的 2 个 UILabel 和第二行中的另一个 UILabel 组成的 TableViewCell。

框架的布局和布局标签在模拟器中工作正常。但是:

1)高度不会随着每个单元格动态增加/减少

2)每当在模拟器中滚动时,表格都会崩溃

有人可以向我解释一下我在这段代码中做错了什么吗?想不通。

这是我尝试创建的单元格的图片:

Talt text http://www.bubl3r .com/photo.JPG

这是我动态分配单元格高度的方法:

#define CELL_PADDING 10.0f
#define IMAGE_SIDE_SIZE 50.0f
#define LABEL_HEIGHT 14.0f
#define LABELWIDTH_CALLSIGN 160.0f
#define LABELWIDTH_DATE 60.0f
#define LABELWIDTH_USER 160.0f
#define FONT_SIZE 11.0f


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {


    RFFlag *aFlag = [flagList objectAtIndex:[indexPath row]];

    CGSize messageConstraint = CGSizeMake(LABELWIDTH_CALLSIGN + LABELWIDTH_DATE + CELL_PADDING,20000.0f);
    CGSize messageSize = [aFlag.msg.station.callsign sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:messageConstraint lineBreakMode:UILineBreakModeWordWrap];
    CGFloat height = MAX(messageSize.height, 44.0f);

    CGFloat cellHeight = height + LABEL_HEIGHT + (CELL_PADDING * 3);

    return cellHeight;
}

这是我的 CelLForRowAtIndexPathMethod:

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

        RFFlag *aFlag = [flagList objectAtIndex:[indexPath row]];
        UITableViewCell *cell;
        UILabel *callsign,*dateposted,*message;

        cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

        if (cell == nil) {

            cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"]autorelease];


            callsign = [[UILabel alloc] initWithFrame:CGRectMake(IMAGE_SIDE_SIZE + (CELL_PADDING*2), CELL_PADDING, LABELWIDTH_CALLSIGN, LABEL_HEIGHT)];
            [callsign setMinimumFontSize:FONT_SIZE];
            [callsign setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [callsign setTag:3];

            [[cell contentView] addSubview:callsign];

            dateposted = [[UILabel alloc] initWithFrame:CGRectMake(CELL_PADDING*3 + IMAGE_SIDE_SIZE + LABELWIDTH_CALLSIGN, CELL_PADDING, LABELWIDTH_DATE, LABEL_HEIGHT)];       
            [dateposted setMinimumFontSize:FONT_SIZE];
            [dateposted setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [dateposted setTag:2];

            [[cell contentView] addSubview:dateposted];


            message = [[UILabel alloc] initWithFrame:CGRectZero];
            [message setLineBreakMode:UILineBreakModeWordWrap];
            [message setMinimumFontSize:FONT_SIZE];
            [message setNumberOfLines:0];
            [message setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [message setTag:1];

            [[cell contentView] addSubview:message];

        }
        if (!message)
            message = (UILabel*)[cell viewWithTag:1];



        [message setText:aFlag.msg.messageData];
        [callsign setText:aFlag.msg.station.callsign];
        [dateposted setText:aFlag.msg.createdDate];


        CGSize messageConstraint = CGSizeMake(LABELWIDTH_CALLSIGN + LABELWIDTH_DATE + CELL_PADDING, 20000.0f);
        CGSize messageSize = [aFlag.msg.messageData sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:messageConstraint lineBreakMode:UILineBreakModeWordWrap];
        [message setFrame:CGRectMake(IMAGE_SIDE_SIZE + (CELL_PADDING*2), LABEL_HEIGHT + (CELL_PADDING*2), LABELWIDTH_CALLSIGN + CELL_PADDING + LABELWIDTH_DATE, MAX(messageSize.height,44.0f))];

        return cell;
    }

I've been trying to create a TableViewCell consisting of 2 UILabels in the first row, and another UILabel in the second row.

The layout of frames & labels works correctly in the simulator. However:

1) The height is not dynamically increasing / decreasing with each cell

2) The Table crashes whenever it is scrolled in the simulator

Can someone please explain to me what I'm doing wrong in this code? Can't figure it out.

Here is a picture of the cell I'm trying to create:

Talt text http://www.bubl3r.com/photo.JPG

This is my method for dynamically allocating cell height:

#define CELL_PADDING 10.0f
#define IMAGE_SIDE_SIZE 50.0f
#define LABEL_HEIGHT 14.0f
#define LABELWIDTH_CALLSIGN 160.0f
#define LABELWIDTH_DATE 60.0f
#define LABELWIDTH_USER 160.0f
#define FONT_SIZE 11.0f


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {


    RFFlag *aFlag = [flagList objectAtIndex:[indexPath row]];

    CGSize messageConstraint = CGSizeMake(LABELWIDTH_CALLSIGN + LABELWIDTH_DATE + CELL_PADDING,20000.0f);
    CGSize messageSize = [aFlag.msg.station.callsign sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:messageConstraint lineBreakMode:UILineBreakModeWordWrap];
    CGFloat height = MAX(messageSize.height, 44.0f);

    CGFloat cellHeight = height + LABEL_HEIGHT + (CELL_PADDING * 3);

    return cellHeight;
}

This is my CelLForRowAtIndexPathMethod:

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

        RFFlag *aFlag = [flagList objectAtIndex:[indexPath row]];
        UITableViewCell *cell;
        UILabel *callsign,*dateposted,*message;

        cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

        if (cell == nil) {

            cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"]autorelease];


            callsign = [[UILabel alloc] initWithFrame:CGRectMake(IMAGE_SIDE_SIZE + (CELL_PADDING*2), CELL_PADDING, LABELWIDTH_CALLSIGN, LABEL_HEIGHT)];
            [callsign setMinimumFontSize:FONT_SIZE];
            [callsign setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [callsign setTag:3];

            [[cell contentView] addSubview:callsign];

            dateposted = [[UILabel alloc] initWithFrame:CGRectMake(CELL_PADDING*3 + IMAGE_SIDE_SIZE + LABELWIDTH_CALLSIGN, CELL_PADDING, LABELWIDTH_DATE, LABEL_HEIGHT)];       
            [dateposted setMinimumFontSize:FONT_SIZE];
            [dateposted setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [dateposted setTag:2];

            [[cell contentView] addSubview:dateposted];


            message = [[UILabel alloc] initWithFrame:CGRectZero];
            [message setLineBreakMode:UILineBreakModeWordWrap];
            [message setMinimumFontSize:FONT_SIZE];
            [message setNumberOfLines:0];
            [message setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [message setTag:1];

            [[cell contentView] addSubview:message];

        }
        if (!message)
            message = (UILabel*)[cell viewWithTag:1];



        [message setText:aFlag.msg.messageData];
        [callsign setText:aFlag.msg.station.callsign];
        [dateposted setText:aFlag.msg.createdDate];


        CGSize messageConstraint = CGSizeMake(LABELWIDTH_CALLSIGN + LABELWIDTH_DATE + CELL_PADDING, 20000.0f);
        CGSize messageSize = [aFlag.msg.messageData sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:messageConstraint lineBreakMode:UILineBreakModeWordWrap];
        [message setFrame:CGRectMake(IMAGE_SIDE_SIZE + (CELL_PADDING*2), LABEL_HEIGHT + (CELL_PADDING*2), LABELWIDTH_CALLSIGN + CELL_PADDING + LABELWIDTH_DATE, MAX(messageSize.height,44.0f))];

        return cell;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

停顿的约定 2024-09-21 10:01:34

您肯定做错的一件事是使用变量 callsign、dateposted 和 message。这些声明在哪里?

一旦开始滚动,iPhone 将重复使用滚动到视图之外的单元格。在这些情况下,您不会为提到的变量分配新值。他们可能引用刚刚被释放的对象。

我需要将这些变量设置为该方法的局部变量。如果 dequeueReusableCellWithIdentifier: 返回一个现有的表格单元格,您需要深入该单元格的子视图以找到三个标签并将它们分配给变量。

One thing your certainly doing wrong is the use of the variables callsign, dateposted and message. Where are these declare?

Once you start scrolling, the iPhone will reuse the cells that are scrolled out of view. In these cases, you don't assign new values to the mentioned variables. They probably refer the object that have just been freed.

I'll need to make these variables local variables of the method. If dequeueReusableCellWithIdentifier: returns an existing table cell, you'll need to dig into the subviews of the cell to locate the three labels and assign them to the variable.s

淑女气质 2024-09-21 10:01:34

也许高度问题与您获取 messageSize 的调用有关,但在不知道 RFFlag 是什么的情况下我无法说更多。

关于崩溃,我认为当重复使用单元格时会发生这种情况:在这种情况下

[callsign setText:aFlag.msg.station.callsign];

被执行,但 callsign 是堆栈中未初始化的变量,可能是任何东西,然后你尝试向它发送消息。与发布日期相同。

顺便说一句,当您创建 UILabels 时,您会导致内存泄漏,因为您从未释放它们。

Maybe the height problem is related to the call where you get messageSize, but i can't say more without knowing what is RFFlag.

About the crash i think this happens when a cell is reused: in that case

[callsign setText:aFlag.msg.station.callsign];

is executed but callsign is an uninitialized variable in the stack which could be anything and you try to dispatch a message to it. Same for dateposted.

And btw, when you create the UILabels you're causing a memory leak because you never release them.

内心旳酸楚 2024-09-21 10:01:34

崩溃是EXC_BAD_ACCESS吗?如果是这样,请尝试

  1. 运行构建并分析 - 它干净吗?仔细看看它所说的一切。

  2. 使用 NSZombiesEnabled 运行:我在博客中介绍了如何执行此操作:

    http://loufranco.com/blog/files/debug -iphone-crash-EXC_BAD_ACCESS.html

    这会导致运行时不会释放对象,而是在您向保留计数为 0 的对象发送消息时发出抱怨。

Is the crash EXC_BAD_ACCESS? If so, try this

  1. Run a Build and Analyze -- is it clean? Take a good look at everything it says.

  2. Run with NSZombiesEnabled: I blogged about how to do that here:

    http://loufranco.com/blog/files/debug-iphone-crash-EXC_BAD_ACCESS.html

    This causes the runtime to not dealloc objects and instead complains if you send messages to objects with 0 retainCount.

一瞬间的火花 2024-09-21 10:01:34

也许这个链接< /a> 可以帮助您解决身高问题。

或者
也许高度问题与获取 messageSize 的调用有关,但在不知道什么是 RFFlag 的情况下我无法说更多。

关于崩溃,我认为当重复使用单元格时会发生这种情况:在这种情况下

[callsign setText:aFlag.msg.station.callsign];

已执行,但 callsign 是堆栈中未初始化的变量,可以是任何内容,并且您尝试向它分派消息。发布日期相同。

顺便说一句,当您创建 UILabels 时,您会导致内存泄漏,因为您从未释放它们。

Maybe this link can help you with the height problem.

or
Maybe the height problem is related to the call where you get messageSize, but i can't say more without knowing what is RFFlag.

About the crash i think this happens when a cell is reused: in that case

[callsign setText:aFlag.msg.station.callsign];

is executed but callsign is an uninitialized variable in the stack which could be anything and you try to dispatch a message to it. Same for dateposted.

And btw, when you create the UILabels you're causing a memory leak because you never release them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文