【问题标题】:Expanded UITableViewCell according to UILabel size根据 UILabel 大小展开 UITableViewCell
【发布时间】:2012-11-14 11:35:46
【问题描述】:

我有一个UITableView 和 4 个UILabel's:标题、正文、作者和日期,他看起来像这样:

我想要完成的是,当用户单击单元格本身时,应向单元格添加另一个标签,“正文”标签,并且单元格应根据此标签大小展开。

类似这样的:

我该怎么做?我搜索了stackoverflow,尝试了一些代码片段,但仍然没有找到正确的解决方案。

谢谢!

编辑 1:14.11.12 14:52

我设法用当前文本改变了 UILabel 的大小:

- (CGRect )resizeLabelByFontSize:(UILabel *)customCellLabel withMaxHeightSize:(CGFloat )maxHeight
{
    CGSize maximumLabelSize = CGSizeMake(239, maxHeight);

    CGSize expectedLabelSize = [customCellLabel.text sizeWithFont:customCellLabel.font constrainedToSize:maximumLabelSize lineBreakMode:customCellLabel.lineBreakMode];

    //adjust the label the the new height.
    CGRect newFrame = customCellLabel.frame;
    newFrame.size.height = expectedLabelSize.height;

    return newFrame;
}

但是如何根据新UILabel的大小改变单元格的大小呢?

【问题讨论】:

  • 你试过那个链接吗,在我的回答中提到..!!!

标签: iphone objective-c ios uitableview uilabel


【解决方案1】:

通过查看问题中的图像

这里是为UILabel创建动态框架的方法看看这个 通过获取UIlabel 的高度和宽度,您可以计算整体高度并可以设置UITableView. 的行高

- (void)setLabeltextWithVerticalAlignTop:(NSString *)theText
{
CGSize labelSize;
// here  labelSize is hard-wired but could use constants to populate the size

labelSize = CGSizeMake(210, 129);//this is just for example
//now create the Size from textString SO that We  could assign this size to the Label.

 CGSize theStringSize = [theText sizeWithFont:lblTitle.font  constrainedToSize:labelSize lineBreakMode:lblTitle.lineBreakMode];
 lblTitle.frame = CGRectMake(lblTitle.frame.origin.x, lblTitle.frame.origin.y, theStringSize.width, theStringSize.height);
 lblTitle.text = theText;

}

调用上述方法要设置描述标签的高度和宽度,您需要传递要在该描述标签上显示的文本。 当您获得该标签的高度后,现在您可以在此基础上调整 TableView 行的高度。

编辑:以上代码只需为 UILabel 创建动态框架

You should take a view of this这就是你要找的......!!!.这里你也可以找到一个示例代码。

编辑:当你编辑你的问题时,它只是你需要将其转换为可运行代码的逻辑。

在你的代码中使用下面的方法为每一行调用,并在其中进行一些计算。

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat rowHeight=0.0;
//here it seems cell have 4 subview added on it.
//so if you could calculate the totla hieht of them.

//so what you really need to do.you just use hieght calculative Method for getting hieght of each of three UILabel
//you need to modify  `setLabeltextWithVerticalAlignTop` method .
rowHeight=   [self setLabeltextWithVerticalAlignTop:@"pass the correspondingText"];// suppose it returns some hieght for FisrtLabel.

//suppoose here you get the 20.0 height here

rowHeight= rowHeight+[self setLabeltextWithVerticalAlignTop:@"pass the correspondingText"];
 

// 假设它为 secondUIlabel 返回一些高度。

//suppoose here you get the 40.0 height here

rowHeight=  rowHeight+ [self setLabeltextWithVerticalAlignTop:@"pass the correspondingText"];

 // suppose it returns some hieght for ThirdUIlabel.
// suppoose here you get the 15.0 height here
//here you have totla height you just need to add some gapping floating value for all of three UIlabel.so that the could not overlap like as.

 rowHeight= rowHeight+20.0;

  //now you can return that total height
  return rowHeight;
 }

注意:这只是您需要将其转换为可运行代码的逻辑。我相信这会有所帮助。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    实现以下方法

    – (void) tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
    {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    
        // cast cell, add label, expand labels etc
    
        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return [indexPath isEqualTo:[tableView indexPathForSelectedRow]] ? /* expanded height */ : 80 /* normal height */;
    }
    

    如果您希望该行在选择另一行后仍保持选中状态,则将自定义 BOOL 属性添加到您的自定义单元格,例如expanded,并用它来确定高度。

    【讨论】:

      【解决方案3】:

      你可以使用 tableView:didSelectRowAtIndexPath

      然后,您可以在该方法中创建代码以取消隐藏正文标签,调整其他所有内容的相对位置。计算新的行高,然后调用 Table View 的 reloadRowsAtIndexPath: withRowAnimation: 方法。

      很抱歉,如果没有太多细节,但希望这能让你走上正轨。

      【讨论】:

        【解决方案4】:

        好的,首先...要扩展你需要这样的东西:

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

        现在是关键:

        • 您应该计算 UITableViewCell 的大小(展开和未展开)
        • 在您实际滚动时这样做可能会很昂贵,并且会给您带来不好的体验

        我的建议:

        • 在您真正结束构建UITableView 之前计算双方,因为您想要动态大小。如果您不这样做,并且所有单元格的扩展尺寸相同,您可以使用 lammmert 所说的。

        【讨论】:

          【解决方案5】:

          NSIndexPath *selectedRow;

           - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
          selectedRow = indexPath;
          }
          
          
           - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
           if(indexPath == selectedRow){
              //return your custom value
          }
          return 100;
          
          }
          

          我觉得应该是这样的

          【讨论】:

            【解决方案6】:

            因此,为了做到这一点,使用扩展的 UITableViewCell,我创建了 2 个不同的自定义单元格,在开始时表格显示第一个单元格,当我单击单元格时,表格显示第二个单元格。就这么简单 - 是的!

            所以我有 UIViewController 和 UITableView 实现表委托方法:

            - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
            {    
                if([self.selectedCellIndexPath isEqual:indexPath])
                {
                    return [self expandedCellHeight:indexPath];
                }
                else
                {
                    return kRegularCellHeight;
                }
            }
            
            -(CGFloat)expandedCellHeight:(NSIndexPath *)indexPath
            {
                CGSize maxSize = CGSizeMake(303, 200);
                NSString* bodyText  = [[self.data objectAtIndex:indexPath.row] objectForKey:kForumMessagesBody];
                CGSize fitSize = [bodyText sizeWithFont:[UIFont systemFontOfSize:13] constrainedToSize:maxSize lineBreakMode:UILineBreakModeWordWrap];
            
                CGFloat height = 384 - 69 + fitSize.height;
                NSLog(@"expandedHeight: %f",height);
                return height;
            }
            
            - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
            {
                // Answer cell
                if ([self.selectedCellIndexPath isEqual:indexPath])
                {
                    cell = [tableView dequeueReusableCellWithIdentifier:[ForumCell expandedAnswerReuseIdentifier]];
                    if (cell == nil)
                    {
                        cell = [ForumCell expandedAnswerCell];
                    }
                    self.expandedCell = cell;
            
                }
                else
                {
                    cell = [tableView dequeueReusableCellWithIdentifier:[ForumCell reqularAnswerReuseIdentifier]];
                    if (cell == nil)
                    {
                        cell = [ForumCell regularAnswerCell];
                    }
                }
            
                cell.labelMedia.text = [self.data objectAtIndex:indexPath.row];
            
                return cell;
            }
            

            我也有自定义单元格,名为ForumCell.hForumCell.m 的类,它有2 个不同的XIB 文件:ForumRegularAnswerCell.xibForumExpandedAnswerCell.xib,我在ForumCell.h 中有以下代码:

            + (NSString*)reqularAnswerReuseIdentifier
            {
                return @"RegularAnswerCellReuseIdentifier";
            }
            
            + (NSString*)expandedAnswerReuseIdentifier
            {
                return @"ExpandedAnswerCellReuseIdentifier";
            }
            
            + (ForumCell*)regularAnswerCell
            {
                NSArray* objs = [[NSBundle mainBundle] loadNibNamed:@"ForumRegularAnswerCell" owner:self options:nil];
                ForumCell* result = [objs objectAtIndex:0];
            
                return result;
            }
            
            + (ForumCell*)expandedAnswerCell
            {
                NSArray* objs = [[NSBundle mainBundle] loadNibNamed:@"ForumExpandedAnswerCell" owner:self options:nil];
                ForumCell* result = [objs objectAtIndex:0];
            
                return result;
            }
            
            - (id)initWithCoder:(NSCoder *)decoder
            {
                self = [super initWithCoder:decoder];
                if (self)
                {
                    _originalCellHeight = self.frame.size.height;
                    _originalLblBodyHeight = self.lblBody.frame.size.height;
                }
                return self;
            }
            

            如果您愿意,也可以使用 2 个以上的 xib。但这是基础。

            享受吧!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-11-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多