Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand UITableView to show all cells in Stack View?

I am having trouble getting my UITableView to appear full height in my Stack View.

My view tree looks as follows:

- View
  - Scroll View
    - Stack View
      - Table View
      - Image View
      - Map View

The table view is dynamically populated with data, which works fine. The issue is that only one row is visible at a time and I have to scroll through the list. What I would like to see happen is for the table view to take as much vertical room as it needs to display all the cells.

I did try adjusting table height as follows, but that just ends up with table that no longer scrolls, though even if it did work I would rather have something more dynamic:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)        
    self.detailsTableView.frame.size.height = 200
}

I am suspecting that it is probably an aspect of the 'stack view' that needs adjusting, but I am not sure at this point. Can anyone suggest an appropriate way?

like image 994
Andre M Avatar asked Mar 08 '16 19:03

Andre M


People also ask

How do I increase the width of a stack view?

Select the top-level stack view and in the Attributes inspector, click the + button next to Spacing: Choose Any Width and Compact Height, then select Add Variation. Set the Spacing to 10 in the new hC field: Build and run.

How do I populate UITableView?

There are two main base ways to populate a tableview. The more popular is through Interface Building, using a prototype cell UI object. The other is strictly through code when you don't need a prototype cell from Interface Builder.

How do you add space between tableView cells?

The way I achieve adding spacing between cells is to make numberOfSections = "Your array count" and make each section contains only one row. And then define headerView and its height. This works great.


2 Answers

I had been encountering the same issue and realized you need a self sizing table view. I stumbled on this answer and created a subclass like @MuHAOS suggested. I did not encounter any issues.

final class IntrinsicTableView: UITableView {

    override var contentSize: CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }


    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }

}
like image 87
Maria Avatar answered Oct 07 '22 05:10

Maria


A UIStackView will compress views wherever it can, to counteract this set a height anchor and width anchor to the UITableView or a priority for its height and width. Here is a working example of how we can be in charge of the dimensions of a table within a stack view.

An extension to instantiate and centrally position the UIStackView

First of all I've written a UIStackView extension so that I don't need to include all the code inside the view controller. Your positioning and setup will be different because you are placing your stack view inside a scroll view, but separating this code out means you can make your own adjustments.

extension UIStackView {
    
    convenience init(axis:UILayoutConstraintAxis, spacing:CGFloat) {
        self.init()
        self.axis = axis
        self.spacing = spacing
        self.translatesAutoresizingMaskIntoConstraints = false
    }
    
    func anchorStackView(toView view:UIView, anchorX:NSLayoutXAxisAnchor, equalAnchorX:NSLayoutXAxisAnchor, anchorY:NSLayoutYAxisAnchor, equalAnchorY:NSLayoutYAxisAnchor) {
        view.addSubview(self)
        anchorX.constraintEqualToAnchor(equalAnchorX).active = true
        anchorY.constraintEqualToAnchor(equalAnchorY).active = true
        
    }
    
}

We don't set a size for the UIStackView only a position, it is the things contained within it that determine its size. Also note the setting of translatesAutoresizingMaskIntoConstraints to false in the UIStackView extension. (It is only required that we set this property for the stack view, its subviews simply inherit the behaviour.)

UITableView class with data source code

Next I've created a basic table class for demo purposes.

class MyTable: UITableView, UITableViewDataSource {
    let data = ["January","February","March","April","May","June","July","August","September","October","November","December"]
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("SauceCell", forIndexPath: indexPath)
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }
}

Setup of stack view and table in view controller

Finally, the important stuff. As soon as we add our table to the stack view all the frame information is disregarded. So we need the final two lines of code to set the width and height for the table in terms that Auto Layout can understand.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let table = MyTable(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
        table.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SauceCell")
        table.dataSource = table

      
        let stack = UIStackView(axis: .Vertical, spacing: 10)
        stack.anchorStackView(toView: view, anchorX: stack.centerXAnchor, equalAnchorX: view.centerXAnchor, anchorY: stack.centerYAnchor, equalAnchorY: view.centerYAnchor)
        
        stack.addArrangedSubview(table)

        
        table.widthAnchor.constraintEqualToAnchor(view.widthAnchor, multiplier: 1).active = true
        table.heightAnchor.constraintEqualToAnchor(view.heightAnchor, multiplier: 0.5).active = true
        
    }
    
    
}

Note that we use addArrangedSubview: not addSubview: when adding views to the stack view.

(I've written blogposts about UIStackView as well as others about Auto Layout in general that might help too.)

like image 34
sketchyTech Avatar answered Oct 07 '22 04:10

sketchyTech