UILabel inside nested UIStackViews inside UITableV

2019-08-01 09:01发布

问题:

I have a tableview cell in one of my tables setup as containing the following view hierarchy

The outer horizontal stackview is pinned to the cell's content view on trailing, leading, bottom and top edges.

The right label is pinned to its parent stackViewHackView on trailing, leading, bottom and top edges

Within my controllers code I've got the cells setup to be dynamic height to fit the content of the cells so they can grow or shrink depending on the content size

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 30.0 

Regarding Auto layout setup. (Relevant priorities in BOLD)

  • Outer Horizontal Stack View
    • Content Hugging Priority == 250
    • Content Compression Resistance Priority == 750
    • Inner Vertical Stack View
      • Content Hugging Priority == 750
      • Content Compression Resistance Priority == 750
      • Left Label 1
        • Content Hugging Priority == 750
        • Content Compression Resistance Priority == 750
      • Left Label 2
        • Content Hugging Priority == 750
        • Content Compression Resistance Priority == 750
      • View (Just to pad out the two left labels to the top of the stack view)
        • Content Hugging Priority == 250
        • Content Compression Resistance Priority == h:750; v:250
    • stackViewHackView (hack to make multiline labels grow properly inside a stack view and cell)
      • Content Hugging Priority == 250
      • Content Compression Resistance Priority == h:250; v:750
        • lower horizontal resistance to allow this view to compress for the left stack view to fit
    • Right Label
      • Content Hugging Priority == 250
      • Content Compression Resistance Priority == h:250; v:750
        • lower horizontal resistance to allow this view to compress for the left stack view to fit

I fill this cell with test data in a simple test app with the following code

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{
  let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath) as! TestTableViewCell


  // Configure the cell...

  if indexPath.section == 0
  {
    cell.leftLabel1?.text = "Label1 aabbccdd"
    cell.leftLabel2?.text = "Label2 aabbccdd"
    cell.rightLabel?.text = "Cell \(indexPath.row) with a 'really really' long string that needs displaying clearly and causing the table cell to resize to fit the content. We're looking for about 3 or 4 lines of text to be displayed"
  }
  else if indexPath.section == 1
  {
    cell.leftLabel1?.text = "Label1 aabbccdd"
    cell.leftLabel2?.text = "Label2 aabbccdd"
    cell.rightLabel?.text = "Cell \(indexPath.row) with a 'really really really' long string that needs displaying clearly and causing the table cell to resize to fit the content. We're looking for about 3 or 4 lines of text to be displayed"
  }
  else
  {
    cell.leftLabel1?.text = "Label1 aabbccdd"
    cell.leftLabel2?.text = "Label2 aabbccdd"
    cell.rightLabel?.text = "Cell \(indexPath.row) with a 'really really really really really really really really' long string that needs displaying clearly and causing the table cell to resize to fit the content. We're looking for about 3 or 4 lines of text to be displayed"
  }

  return cell
}

Which results in the following rendering in the simulator on an iPhone 7 target

The middle tableview cell is the sort of output i'd like to get all the time. I don't want the left labels to EVER truncate, their content will always be small enough to fit along with the right hand side. Yet given certain content on the right hand side the longer Label 2 can sometimes be truncated as you can see in the top and bottom rows.

I've setup the content compression resistance such that all the elements on the left have high resistance to compression with the elements on the right set to lower resistance so that they should compress to make space for the left side elements.

Any ideas why this is happening or how I can stop it happening so my labels always display properly?

Cheers!

回答1:

(Added as answer per the OP)

This may just be "how it seems to me" but... I've seen a number of people using stack views wrapped in stack views wrapped in stack views, when simple views with constraints can do the job.

Take a look at how I've done it in this project: github.com/DonMag/CellTest2

It's really very simple, and you can look at the labels and see just how little I had to do in terms of changing priorities. I used your sample strings, and added a few more cases to test variations.