2
votes

I've spent several days trying to figure this out, but there doesn't seem to be a solution. I have a very basic UITableView cell with two labels in it. One of them will be one line, the second will be multiline. The second one will be varying in heights. Here is an example of what I'm trying to produce ( UIStackViews inside of UITableViewCells ) :

enter image description here

From reading hundreds of SO posts, hundreds of blogs, scouring the Apple Developer sites, there seems to be an unlimited amount of ways one could write this. After having experimented with hundreds of different ways, I still can't manage to display the text like so. I think some of the trouble comes from the fact that I'm using 3 different UITableView cell variations in one UITableView.

Here is my code from my latest attempt cellForRowAtIndexPath :

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell : UITableViewCell!

    let (parent, isParentCell) = self.findParent(indexPath.row)

    if !isParentCell {

        let categories = ["words", "translation","commentary"]

        if categories[parent] == "words" {

            cell = tableView.dequeueReusableCellWithIdentifier(childWordsCellIdentifier, forIndexPath: indexPath) as UITableViewCell

            // Reset content
            for subview in cell.contentView.subviews {
                subview.removeFromSuperview()
            }
            cell.prepareForReuse()


            let words                   = self.page.valueForKey("words")!.allObjects as! [Word]
            let wordsInOrder            = words.sort({Int($0.order!) < Int($1.order!) })
            let word                    = wordsInOrder[indexPath.row - 1]

            let labelWidth              = (self.view.frame.width - 80) / 2


            let wordLabel               = UILabel(frame: CGRectZero)
            wordLabel.text              = word.valueForKey("sanskrit") as? String
            wordLabel.font              = UIFont(name: "EuphemiaUCAS-Bold", size: 16)
            wordLabel.numberOfLines     = 0
            wordLabel.translatesAutoresizingMaskIntoConstraints = false
            wordLabel.layer.borderColor = UIColor.greenColor().CGColor
            wordLabel.layer.borderWidth = 1.0
            let widthWordConstraint = wordLabel.widthAnchor.constraintEqualToConstant(labelWidth)
            widthWordConstraint.priority = 300
            widthWordConstraint.active = true

            let englishWordLabel           = UILabel(frame: CGRectZero)
            englishWordLabel.text          = "Foobar don't want to play my game with my anymore."
            englishWordLabel.font          = UIFont(name: "STHeitiTC-Light", size: 16)
            englishWordLabel.numberOfLines = 0
            englishWordLabel.preferredMaxLayoutWidth = labelWidth
            englishWordLabel.translatesAutoresizingMaskIntoConstraints = false
            let englishWordConstraint = englishWordLabel.widthAnchor.constraintEqualToConstant(labelWidth)
            englishWordConstraint.priority = 300
            englishWordConstraint.active = true
            englishWordLabel.layer.borderColor = UIColor.blueColor().CGColor
            englishWordLabel.layer.borderWidth = 1.0

            let stackView = UIStackView()
            stackView.axis = .Horizontal
            stackView.distribution = .FillProportionally
            stackView.alignment = .FirstBaseline
            stackView.spacing = 15
            stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
            stackView.layoutMarginsRelativeArrangement = true

            stackView.addArrangedSubview(wordLabel)
            stackView.addArrangedSubview(englishWordLabel)

            stackView.translatesAutoresizingMaskIntoConstraints = false

            englishWordLabel.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
            englishWordLabel.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true


            cell.contentView.addSubview(stackView)

            cell.contentView.layoutIfNeeded()


        } else {

            cell = tableView.dequeueReusableCellWithIdentifier(childCellIdentifier, forIndexPath: indexPath) as UITableViewCell

            // Reset content
            cell.textLabel!.text = ""
            for subview in cell.contentView.subviews {
                subview.removeFromSuperview()
            }
            cell.prepareForReuse()

            cell.textLabel!.text        = self.page.valueForKey(categories[parent]) as? String
            cell.textLabel!.textColor   = UIColor(red: 35/255.0, green: 31/255.0, blue: 32/255.0, alpha: 1.0)
            cell.textLabel!.font        = UIFont(name: "STHeitiTC-Light", size: 16)
        }
    }
    else {
        // Parent
        cell = tableView.dequeueReusableCellWithIdentifier(parentCellIdentifier, forIndexPath: indexPath)
        cell.textLabel!.text        = self.dataSource[parent].title
        cell.textLabel!.textColor   = UIColor(red: 66/255.0, green: 116/255.0, blue: 185/255.0, alpha: 1.0)
        cell.textLabel!.font        = UIFont(name: "STHeitiTC-Light", size: 20)
    }

    cell.selectionStyle                                       = .None
    cell.textLabel!.translatesAutoresizingMaskIntoConstraints = false
    cell.textLabel!.numberOfLines                             = 0
    cell.textLabel!.lineBreakMode = .ByWordWrapping

    return cell
}

Which produces this :

enter image description here

11
Why don't you create a custom subclass and set layout constraints in there?Ozgur Vatansever
Yah maybe once I'm all set up and want to DRY up the code..Trip
Why are you using stackview? To implement multiline label or you plan to add more view vertically below multiline label?BangOperator
@DineshHudinwal To align two uilabels to their top baselineTrip

11 Answers

3
votes

I suggest you don't use stack view for this . Just take custom cell with Label according to your requirement and cell will resize automatically according to Label text size.

Check , here i have attached demo.

UITableview cell Autoresize According to textsize

Output :-

enter image description here

In viewdidload

super.viewDidLoad()
        self.tblView.estimatedRowHeight = 100;
        self.tblView.rowHeight = UITableViewAutomaticDimension;
        self.tblView.setNeedsLayout()
        self.tblView.layoutIfNeeded()

Dont forget to set Numberoflines=0 of UILabel property.

enter image description here

Edit :- If you need step by step guide regarding how to set constrain to UILabel ,

check this link ,

Adjust UILabel height depending on the text

Edit :- Here i have take 2 label in cell according to your above image. Just set constrain like this .

enter image description here

Label 1 :- Top , Leading , (Height and width According to your requirement)

Label 2 :- Top , Bottom , Leading from Label 1, Trailing from Superview

2
votes

The height of a table view cell is decided by the table based on the rowHeight property, or on the return value of optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat from the table view delegate.

The height that may be set by the programmer for the UITableViewCell through its frame property is ignored!

Hence you need to figure out the desired height of each cell programatically. Then you need to implement optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat from the table view delegate for each of the cells.

If the size of a cell changes while the table view is displayed, you need to either:

  • reload the table with reloadData() from UITableView, or
  • update the cell with func reloadRowsAtIndexPaths(_ indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation) from UITableView.

Edit

Actually since you are using constraints in you view it should work without using ``.

Try to replace the code in if categories[parent] == "words" { .. } with:

        cell = tableView.dequeueReusableCellWithIdentifier(childWordsCellIdentifier, forIndexPath: indexPath) as UITableViewCell

        // Reset content
        for subview in cell.contentView.subviews {
            subview.removeFromSuperview()
        }
        cell.prepareForReuse()


        let words                   = self.page.valueForKey("words")!.allObjects as! [Word]
        let wordsInOrder            = words.sort({Int($0.order!) < Int($1.order!) })
        let word                    = wordsInOrder[indexPath.row - 1]


        let wordLabel               = UILabel(frame: CGRectZero)
        wordLabel.text              = word.valueForKey("sanskrit") as? String
        wordLabel.font              = UIFont(name: "EuphemiaUCAS-Bold", size: 16)
        wordLabel.numberOfLines     = 0
        wordLabel.translatesAutoresizingMaskIntoConstraints = false
        wordLabel.layer.borderColor = UIColor.greenColor().CGColor
        wordLabel.layer.borderWidth = 1.0

        let englishWordLabel           = UILabel(frame: CGRectZero)
        englishWordLabel.text          = "Foobar don't want to play my game with my anymore."
        englishWordLabel.font          = UIFont(name: "STHeitiTC-Light", size: 16)
        englishWordLabel.numberOfLines = 0

        let stackView = UIStackView()
        stackView.axis = .Horizontal
        stackView.distribution = .FillProportionally
        stackView.alignment = .Fill  // EDIT
        stackView.spacing = 15
        stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
        stackView.layoutMarginsRelativeArrangement = true

        stackView.addArrangedSubview(wordLabel)
        stackView.addArrangedSubview(englishWordLabel)

        stackView.translatesAutoresizingMaskIntoConstraints = false

        cell.contentView.addSubview(stackView)
        cell.contentView.leadingAnchor.constraintEqualToAnchor(stackView.leadingAnchor).active = true
        cell.contentView.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
        cell.contentView.trailingAnchor.constraintEqualToAnchor(stackView.trailingAnchor).active = true
        cell.contentView.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true

        cell.contentView.layoutIfNeeded()

Also I would have used two different cells classes for this task rather than removing the views in the contentView.

Please let me know how it goes!

2
votes

First of all, unless you need a UIStackView for some other purpose that you're not mentioning in your question, don't use them. Multi-line labels and dynamic height cells work well without them (don't needlessly complicate the code if they are not necessary).

There are no bugs in iOS that stop this from working, that I'm aware of. Dynamically sized cells work great with Auto Layout, all you need to do is set the correct constraints in the cells and set the rowHeight and estimatedRowHeight properties of the table view.

The most likely reason this is not working for you is that you have not put all the needed constraints in your cell. The needed constraints are:

  1. A top constraint from your cell content (i.e. your multi-line label) to the top of the cell content view
  2. A leading constraint from your single-line label to the left of the cell
  3. A trailing constraint from your multi-line label to the right of your cell
  4. A bottom constraint from the bottom of your multi-line label to the bottom of your cell

I think you're missing point 4.

Edit

According to your comments, you're using a UIStackView so as to align the top baselines between the single and the multi-line labels. By this, I understand you want your labels to align like this:

enter image description here

To get this behaviour, you don't need a UIStackView. Just give the labels constraints to allow the multi-line label to define the cell height. The following image shows the top baselines aligned between the two labels (i.e. the first lines of each label are aligned).

enter image description here

Notice how the left label only needs a leading and top constraint, while the right label needs a top, trailing and bottom, because it defines cell height.

In summary, dynamic table view cells require three things:

  1. tableView.rowHeight = UITableViewAutomaticDimension
  2. tableView.estimatedRowHeight = 100
  3. The cell content must have all four constraints (leading, trailing, top and bottom) to define cell height.
1
votes

What you want to achieve can be done by a simple implementation of heightForRowAtIndexPath from the tableView delegate.

If you're unsure what cell should have what height you can just calculate it on runtime.

1
votes

For this you need to make use of Self sizing table view cell i.e. table view itself calculates height required for each cells to display it's content it can be achieved in two lines of code:

Step1: set estimate height for table view tableView.estimatedRowHeight = 33.0 step2: set tableView's row height to UITableViewAutomaticDimension tableView.rowHeight = UITableViewAutomaticDimension

Here is the tutorial for detail description http://www.appcoda.com/self-sizing-cells/

1
votes

The approach i will be following:

I will create a UIView SubClass as a container view which will contain "word label" and "english word label". it's much easier, seperate code and maintanable.

I will create a cell subclass and use this container view as subView of cell'scontent view.

I will then use this whole set up in cellForRowAtIndex.

I will also make some code implementation in heightForRow. As to make cell row dynamic height at run time u must implementing this method heightForRow.

The sample Output will some thing like below, it has one UIImageView, and Two UILabel and custom gray seperator. This dynamic cell height is based on what ever image height and what ever string length to be shown in UILabel:

simple dynamic cell height based on what ever image height and what ever image length

I will share some code snippet for you help. So here goes some conceptual code example for container view:

Most important constraint setup for container view say (VenueViewContainer:UIView) is as below, (for your case you can make labels horizontally, instead of vertical):

"V:|-0-[venueImage]-10-[venueName]-2-[sportName]-10-[lblSeperator(10)]",
"H:|-0-[venueImage]-0-|",
"H:|-20-[venueName]-20-|",
"H:|-20-[sportName]-20-|",
"H:|-0-[lblSeperator]-0-|",

Be sure to set these two properties for your labels:

[lbl setNumberOfLines:0];

[lbl setLineBreakMode:NSLineBreakByWordWrapping];

In your VenueViewContainer implementation file make a method:

/*!This method is responsible for getting view dynamic height .*/

-(float)getViewHeight
{
[self layoutIfNeeded];

CGFloat maxY = 0;

for (UIView *subview in self.subviews) {

    maxY = MAX(CGRectGetMaxY(subview.frame),maxY);

}

return maxY;

}

/*!
 This method is responsible for set up Venue.
 @param venue object
 */

#pragma -mark data population

- (void)setupViewWithVenue:(Venue *)venue
{
    self.venueLabel.text = @"my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue my venue last";

    self.sportName.text = @"my sport my sport my sport my sport my sport  my sport my sport my sport my sport my sport my sport my sport my sport my sport last";

    [self.venueImage setImageWithURLString:venue.venueImageUrl defaultImage:[UIImage imageNamed:@"venueinfo_main"]];

}

Now lets talk about custom cell. the UITableViewCell subclass. The implementation is some thinh like this:

    @implementation VenueCellTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self) {

        self.selectionStyle = UITableViewCellSelectionStyleNone;

        [self setUpContainer];

        [self setUpConstraints];

    }

    return self;
}

/*!
 This method is responsible for set up Container
 */

-(void)setUpContainer{

    aViewContainer = [[VenueViewContainer alloc] initWithFrame:CGRectZero];

    [aViewContainer setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self.contentView addSubview:aViewContainer];

}

/*!constraints setup*/

-(void)setUpConstraints{

    /*!
     dictionary of views for autolayout
     */
    NSMutableDictionary* views;

    views = [NSMutableDictionary new];

    UIView *parentView = self.contentView;

    views[@"aViewContainer"] = aViewContainer;

    views[@"parentView"] = parentView;

    NSArray* constraints;

    NSString* format;

    /*!
     layouting horizontal
     */
    format = @"|-0-[aViewContainer]-0-|";

    constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];

    [parentView addConstraints:constraints];

    /*!
     layouting vertical
     */
    format = @"V:|-0-[aViewContainer]-0-|";

    constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];

    [parentView addConstraints:constraints];
}
/*!
 This method is responsible for set up venue
 @param venue object
 */

- (void)setupCellWithVenue:(Venue *)venue
{
    [aViewContainer setupViewWithVenue:venue];
}
/*!
 This method is responsible to get cell height dynamically
 @param venue object
 */

-(float)getCellHeight
{
   return [aViewContainer getViewHeight];
}

Thats it related to customixation of your cell.

now talk about cellForRow and heightForRow:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    VenueCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVenueCellIdentifier];

    if (nil == cell) {
        cell = [[VenueCellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:kVenueCellIdentifier];
    }

    [cell setBackgroundColor:[[AWPViewFactory sharedInstance]getColor:@"colorWhite"]];

#pragma uncomment below line as per ur need
//    Venue *venue = [_dataSourceArray objectAtIndex:indexPath.row];
    [cell setupCellWithVenue:nil];

    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }

    return cell;
}

#pragma mark - UITableViewDelegate methods

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Use the dictionary of offscreen cells to get a cell for the reuse identifier, creating a cell and storing
    // it in the dictionary if one hasn't already been added for the reuse identifier.
    // WARNING: Don't call the table view's dequeueReusableCellWithIdentifier: method here because this will result
    // in a memory leak as the cell is created but never returned from the tableView:cellForRowAtIndexPath: method!
    VenueCellTableViewCell *cell = [self.offscreenCells objectForKey:kVenueCellIdentifier];
    if (!cell) {
        cell = [[VenueCellTableViewCell alloc] init];
        [self.offscreenCells setObject:cell forKey:kVenueCellIdentifier];
    }

    // Configure the cell for this indexPath

#pragma uncomment below line as per ur need

//    Venue *venue = [_dataSourceArray objectAtIndex:indexPath.row];
    [cell setupCellWithVenue:nil];

    return [cell getCellHeight];
}

couple of things i have to not use in above aproach:

1. No use of automatic row height calculation property. 2.No use of estimated height 3.No need of unnecessary updateConstraints. 4.No use of Automatic Preferred Max Layout Width. 5. No use of systemLayoutSizeFittingSize (should have use but not working for me, i dont know what it is doing internally), but instead my method -(float)getViewHeight working and i know what it's doing internally.

i have shared you most relevant code blocks, i have not still worked on swift. But basics remains same. Thanks

1
votes

This is very easy.lets go step by step.

1. set the estimatedRowHeight of table view.It makes easy and fast to load the cell.

2.set the rowHeight property of tableview as UITableViewAutomaticDimension.and don't use heightForRowAtIndexPath.

3.put the all top bottom leading and trailing constraint on both Label.its important.

Lets rock and roll no need to use stackView

1
votes

As of iOS 9.1 UIStackView doesn't implement intrinsicContentSize: so the table view can't calculate the height of each cell, thus they are displayed at the estimated height instead.

So, ideally you would simplify your code to mean you don't use a stack view and you don't keep adding and removing (and creating and destroying) views all the time. The root of the solution is to not use a stack view though.

You can continue to use a stack view if you want, but you'll need to create a subclass and implement intrinsicContentSize:. Your reason for using the stack view shouldn't be required though as you can configure the constraints to match first baselines.

1
votes

As others have mentioned, make sure you're letting the table view cells dynamically resize with:

tableView.estimatedRowHeight = <estimatedHeightValue>
tableView.rowHeight = UITableViewAutomaticDimension

But you've mentioned that you're already doing this.

The rest of the problem is a case of missing constraints. You've already told autolayout that you want your multi-line label to match the top and bottom of the stack view, as in the code below:

englishWordLabel.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
englishWordLabel.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true

But you haven't mentioned to autolayout how this stack view relates to the cell's content view (its superview). This is necessary for dynamically-sized cells because according to Apple:

To define the cell’s height, you need an unbroken chain of constraints and views (with defined heights) to fill the area between the content view’s top edge and its bottom edge. If your views have intrinsic content heights, the system uses those values. If not, you must add the appropriate height constraints, either to the views or to the content view itself.

Your labels have intrinsic content, so that's no problem, but in order to complete the "unbroken chain," you need to tell autolayout that the stack view's top and bottom should be equal to the content view's top and bottom, like so:

// stackView.superview! is the table view cell's content view
stackView.topAnchor.constraintEqualToAnchor(stackView.superview!.topAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(stackView.superview!.bottomAnchor).active = true

Add these two lines after you've added the stack view to the content view, and I believe you'll be in business.

FYI, even if you're programmatically adding these views to your cells like you are, you can still visually debug layout issues quite well with Xcode's awesome Capture View Hierarchy ability. While your app is running from Xcode, click the menu item Debug > View Debugging > Capture View Hierarchy. It's very easy to see what's going on in your view hierarchy, what constraints are active, where your disappearing views went, etc..

2nd FYI, destroying views and then reinstantiating new ones every time a cell appears on screen significantly degrades performance while scrolling. As much as you can, you'll want to take existing views from dequeued cells and reassign their contents with the proper content for that row (and thus avoid view instantiation). You can still do this using your purely-programmatic way of doing things by dequeueing a cell and calling cell.viewWithTag for each possible view. If the method returns nil, you do a one-time instantiation of the view for the cell and give the view a tag (let's say 1 for wordLabel and 2 for englishWordLabel). Then assign the proper content for the row to the view.

1
votes

I've had very similar problems with autoLayout time and time again. I don't use stackViews much, I typically use them when I have a requirement to add / remove or show / hide a view. When not doing that I opt for just using constraints. I feel the stackviews are quite buggy in quite a few circumstances. Particularly in xib's. I don't know why that makes a difference, but it seems to always cause warnings that I can't remove, when using more than 1 label.

That being said, autoLayout isn't without its issues either, and they all mainly center around preferredMaxLayoutWidth.

To explain, in order for AutouLayout to calculate the height of a label, it needs to know what width the label can be. When you have multiple labels together, particularly in a tableViewCell, this causes all manner of issues.

I asked and subsequently answered a related question here several days later.

What I did is added a subclass of UILabel that always ensures preferredMaxLayoutWidth is updated whenever the label is modified. I've recently updated it for iOS 8, iOS 9 and a separate issue I found with modal views.

So the full steps are:

  1. Create the UIlabel subclass.
  2. Create a cell with your labels laid without UIStackViews.
  3. Set the number of Lines to 0 for one or both labels depending on your usecase.
  4. Set the Labels to be of the type of your subclass.
  5. Implement the estimatedHeightForRowAtIndexPath method to make a guess at what the height might be.
  6. Calculate the height of the cell inside heightForRowAtIndexPath.


To Calculate the height, you can use something like this (which I have abstracted away into a helper method that I can reuse more easily)

// Set the cell data first, i.e. the label text, any programmatic  fonts, font sizes etc.


if let tempCell = cell as? UITableViewCell
{
    tempCell.width = tableView.width

    let size = tempCell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

    if tableView.separatorStyle != UITableViewCellSeparatorStyle.None
    {
        // +0.5 for seperator
        return size.height+0.5
    }
    else
    {
        return size.height
    }
}

I have combined this with a protocol that makes all cells take in a dictionary to set their data. Then I can wrap up this method to take in and pass in a dictionary and reuse the code over and over again.

This has been working seamlessly for me for a very long time.

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


    NSString *firstLable = firstLable.text;
    NSString *secondLable = SecondLable.text;



    CGSize constraint = CGSizeMake(cell.frame.size.width/2, 20000.0f);
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
    CGRect firstLableRect = [firstLable boundingRectWithSize:constraint
                       options:NSStringDrawingUsesLineFragmentOrigin
                       attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f],      
                        NSParagraphStyleAttributeName: paragraphStyle.copy} context:nil];


    CGRect secondLableRect = [secondLable boundingRectWithSize:constraint
                              options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f],                                       NSParagraphStyleAttributeName: paragraphStyle.copy}context:nil];


    float max = MAX(firstLableRect.size.height, secondLableRect.size.height) + 20;


    //20 for spacing 10 pc above and 10 pc below 


    return max ;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier=@"cellIdentifier";
    UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    cell.selectionStyle =UITableViewCellSelectionStyleNone;



    NSString *lable1 = @"first label text";
    NSString *lable2 = @"second lable text";

    CGSize constraint = CGSizeMake(cell.frame.size.width/2-10, 20000.0f);
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
    CGRect firstLableRect = [lable1 boundingRectWithSize:constraint
                             options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f],
                             NSParagraphStyleAttributeName: paragraphStyle.copy} context:nil];


    CGRect secondLableRect = [lable2 boundingRectWithSize:constraint
                              options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Your App Font" size:16.0f],                                       NSParagraphStyleAttributeName: paragraphStyle.copy}context:nil];



    UILabel *firstLable = [[UILabel alloc]initWithFrame:CGRectMake(5,10,constraint.width,firstLableRect.size.height)];
    [firstLable setLineBreakMode:NSLineBreakByWordWrapping];
    firstLable.minimumScaleFactor = 15.0f;
    [firstLable setNumberOfLines:0];
    firstLable.textAlignment = NSTextAlignmentLeft;
    [firstLable setFont:[UIFont fontWithName:@"your App font" size:16.0f]];
    [cell.contentView addSubview:firstLable];


    UILabel *secondLable = [[UILabel alloc]initWithFrame:CGRectMake(cell.frame.size.width/                       2+5,10,constraint.width,secondLableRect.size.height)];
    [secondLable setLineBreakMode:NSLineBreakByWordWrapping];
    secondLable.minimumScaleFactor = 15.0f;
    [secondLable setNumberOfLines:0];
    secondLable.textAlignment = NSTextAlignmentLeft;
    [secondLable setFont:[UIFont fontWithName:@"your App font" size:16.0f]];

    [cell.contentView addSubview:secondLable];

    return cell;
}