简体   繁体   English

根据UILabel大小扩展了UITableViewCell

[英]Expanded UITableViewCell according to UILabel size

I have a UITableView with 4 UILabel's : Title, Body, Author and Date, he looks like this: 我有一个带有4个UILabel's UITableView :标题,正文,作者和日期,他看起来像这样:

cell55

What I want to accomplish is, when user click on the cell itself, another label should be added to the cell, the "Body" label and the cell should expand according to this label size. 我要实现的是,当用户单击单元格本身时,应向该单元格添加另一个标签,“ Body”标签,并且该单元格应根据此标签大小进行扩展。

Something like this: 像这样:

cellblsize

How can I do that? 我怎样才能做到这一点? I've searched stackoverflow, tried some code pieces, but still didn't found the right solution. 我已经搜索了stackoverflow,尝试了一些代码,但是仍然没有找到正确的解决方案。

Thanks! 谢谢!

Edit 1: 14.11.12 at 14:52 编辑1:14.11.12 at 14:52

I managed to change the size of the UILabel with the current text: 我设法用当前文本更改了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;
}

But how can I change the size of the cell according to the size of the new UILabel? 但是,如何根据新的UILabel的大小更改单元格的大小?

By seeing Images in Question 通过查看有问题的图像

Here is the method which just create the Dynamic FRAME for UILabel have a look at this By getting the Height and Width for UIlabel you can calculate the Whole height and could set the Row Height of UITableView. 这是刚刚为UILabel创建动态FRAME的方法。通过获取UIlabel的高度和宽度,您可以计算出整个高度并可以设置UITableView.的行高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;

}

Call Above Method For setting the height and Width of description Label you need to pass the text to be shown on that description label. 调用上方方法要设置描述标签的高度和宽度,您需要传递要在该描述标签上显示的文本。 As you gets the height for that Label, Now On the Basis of this You can Adjust the heigh of Row of TableView. 当您获得该标签的高度时,现在就可以基于此标签来调整TableView行的高度。

EDIT:Above Code Just Create the Dynamic Frame For The UILabel 编辑:上面的代码只是为UILabel创建动态框架

You should take a view of this this is what you looking for....!!!.here you would find a sample code too. 您应该对此有所了解,在这里也可以找到示例代码。

EDIT:As you edited your Question see ,it just the logic which you need to convert it into runnable code here it is. 编辑:当您编辑问题时,看到的只是将其转换为可运行代码所需的逻辑。

Use Below Method in Your Code called for each row, and make some calculation inside it. 在代码中对每一行使用“以下方法”,并在其中进行一些计算。

 - (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"];

// suppose it returns some hieght for secondUIlabel. //假设它为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;
 }

Note:This is just logic you need to convert it into runnable code.i am sure this can help. 注意:这只是您需要将其转换为可运行代码的逻辑。我确信这会有所帮助。

I hope it may help you. 希望对您有帮助。

Implement the following methods 实现以下方法

– (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 */;
}

If you want the row to stay selected even after another row is selected then add a custom BOOL property to your custom cell, eg expanded , and use that to determine the height. 如果您希望即使在选择了另一行之后该行仍保持选中状态,则向自定义单元格添加一个自定义BOOL属性,例如, expanded ,并使用该属性来确定高度。

You can use tableView:didSelectRowAtIndexPath 您可以使用tableView:didSelectRowAtIndexPath

In that method you can then create your code to unhide the body label, adjust the relative positions of everything else. 然后,在该方法中,您可以创建代码以取消隐藏正文标签,调整其他所有内容的相对位置。 Calculate the new height of the row and then call the Table View's reloadRowsAtIndexPath: withRowAnimation: method. 计算行的新高度,然后调用表视图的reloadRowsAtIndexPath:withRowAnimation:方法。

Sorry if there's not a lot of detail in that, but hopefully that should get you on the right track. 很抱歉,如果其中没有太多细节,但希望可以使您走上正确的道路。

Ok, firstly... To expand you need something like this: 好吧,首先...要扩展,您需要这样的东西:

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

Now here is the catch: 现在这里是要抓住的地方:

  • You should calculate the size of the UITableViewCell (expanded and non-expanded) 您应该计算UITableViewCell的大小(展开和未展开)
  • Doing so when you are actually scrolling might be expensive and will give you a bad experience 实际滚动时这样做可能会很昂贵,并且会给您带来糟糕的体验

My advice: 我的建议:

  • Calculate both sides, before you have actually conclude to build the UITableView , since you want to have dynamic sizes. 在实际结束构建UITableView之前,请计算双方,因为您希望具有动态大小。 If you don't and all cells will have the same size expanded, you can use what lammmert said. 如果您不这样做,并且所有单元格都将扩展相同的大小,则可以使用lammmert所说的内容。

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;

}

I think it will look something like that 我认为它看起来像那样

So, in order to do this, using expended UITableViewCell, i've created 2 different custom cells, at start the table is showing the first cell, when I click on the cell, the table is showing the second one. 因此,为了执行此操作,我使用了扩展的UITableViewCell,创建了2个不同的自定义单元格,在开始时该表显示了第一个单元格,当我单击该单元格时,该表显示了第二个单元格。 Its that easy - yeah! 就是这么简单-是的!

So I have the UIViewController with the UITableView that implements the table delegate methods: 因此,我拥有带有实现表委托方法的UITableView的UIViewController:

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

I also have custom cell, the class called ForumCell.h and ForumCell.m and it has 2 different XIB files: ForumRegularAnswerCell.xib and ForumExpandedAnswerCell.xib , I have the following code inside ForumCell.h : 我也有自定义单元格,该类称为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;
}

You can also use more than 2 xibs if you'd like its up to you. 如果您愿意,可以使用2个以上的xib。 but this is the basics. 但这是基础。

Enjoy! 请享用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM