2

I have a UITableViewController embedded in a UIView container, which is at the bottom of a UIScrollView in a UIViewController. Here is a screenshot of the current configuration in the storyboard.

screenshot

The UITableView will contain responses to the selected post. Because the height and number of responses in the UITableView will be variable, I want the UIView container's height to change based on the height of the table. The current (undesirable) behavior is the UIView container stays a constant height, and scrolls when the UITableView height is greater than the UIView containter's height.

The most viable method seems to be having the UITableViewController pass the height of the table to the UIViewController using prepareForSegue, and then set the UIView's height to that passed value. However, I can't seem to set a value with the height of the table until after prepareForSegue is run.

What Isn't Working

  1. Set the identifier of the embed segue between the UIView and the UITableViewController to "embedSegue"
  2. At the top of the the embedded UITableViewController class, create a variable to hold the height of the table:

    var tableHeight: CGFloat!
    
  3. Still in the embedded UITableViewController, override viewDidLoad like so, printing passedHeight to the console for checking:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.tableView.estimatedRowHeight = 68.0
        self.tableView.rowHeight = UITableViewAutomaticDimension
    
        self.tableHeight = self.tableView.contentSize.height
        print(tableHeight)
    }
    
  4. In the UIViewController class that contains the UIView container, create a variable to hold the value passed from the UITableViewController:

    var viewHeight: CGFloat!
    
  5. Still in the UIViewController, override prepareForSegue like so, setting viewHeight to the passed tableHeight value, and printing viewHeight to the console for checking:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "embedSegue" {
            let responseTableView = segue.destinationViewController as! ResponseViewController
    
            self.viewHeight = responseTableView.tableHeight
    
            if viewHeight == nil {
                print("Nil")
            } else {
                print(viewHeight)
            }
        }
    }
    
  6. When I run the app, viewHeight prints as Nil first, then tableHeight prints, which means prepareForSegue has run prior to tableHeight being set.

I have also tried other methods besides prepareForSegue, including calling various functions on the UIView container in viewDidLayoutSubviews() like:

  • .sizeThatFits()
  • .needsUpdateConstraints()
  • .layoutIfNeeded()

However, the UIView container remains the same height as set in the storyboard.

As an epilogue, this is my first StackOverflow post, and I'm excited to be joining the community. Please do let me know if I can clarify my question. Thank you for taking the time.

K. Thorspear
  • 473
  • 3
  • 12

1 Answers1

1

Instead of using a UIViewController with a UIScrollView containing three UIViews, I created one UITableView with three custom cells. Each cell has their own custom UITableViewCell class for flexibility.

This meant I lost the ability to use constraints to dynamically change the height of each section. I wanted the Post Title and Post Text to be centered on a fullscreen image. To achieve this, I added the logic below:

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if indexPath.row == 0 {
            //Fullscreen image cell - the "20" is for the status bar
            return tableView.frame.size.height - self.navigationController!.navigationBar.frame.size.height - 20
        } else {
            //Just use the current rowHeight
            return self.tableView.rowHeight
        }
    }

References

How to embed a UITableView in a UIScrollview
A short answer to a similar question which sparked the idea

UITableview with more than One Custom Cells with Swift
Detailed explanation of how to create a UITableView with 3 custom UITableViewCells

Community
  • 1
  • 1
K. Thorspear
  • 473
  • 3
  • 12