1

I'm trying to create a custom dialog with a UITableView inside. What I want to achieve is to have the lowest height possible, meaning it should be only wrapping the tableview.
BUT when the tableview has too many items (meaning its height is bigger than the screen), I want the dialog to have 20 px margin from the screen top and bottom.
So if the tableview has 2 items, the height of the dialog should be for example 20 px. But if the tableview has 200 items, the height of the dialog should take almost the entire screen height and have its content scrollable.

Dialog with few items
Dialog with multiple items

Currently if the tableview has multiple items, I can only see some items and the top and bottom of the dialog disappear.
Thanks.

EDIT: I forgot to mention I intend to achieve this using the storyboard only, using constraints and changing priority in content hugging and compression.

Guz F
  • 31
  • 4

4 Answers4

1

My answer will include several parts. They are solving a more general question of how to efficiently work with dialogs.

  1. To create dialog use UIViewControllerTransitioningDelegate, UIPresentationController and UIViewControllerAnimatedTransitioning. It's a long way, but it will make your dialogs presentation reusable.
  2. To determine size of the dialog with table inside of it, set peferredContentSize property of your dialog view controller. This property will be used by UIPresentationController to set dialog height. Before setting peferredContentSize you can adjust the height to the margins you like.
  3. To calculate size of table view you can use several options. table.layoutIfNeeded() worked for me.

Update: check out the article I wrote about this approach.

RealNmae
  • 630
  • 9
  • 20
1

GOT IT WORKING!
All I had to do was change the top and bottom constraints from "=" to ">=". So now it allows the dialog to have a smaller height but not bigger than the screen. No code needed.
Thanks everybody for your help.

Guz F
  • 31
  • 4
0

I guess that you know how many items you have before present the dialog and I guess that you dialog is a custom view (xib)

if this premises are true, you can resolve whit this line.

let dialog = CustomDialog(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: (heighCell * elements) + (heightButtonClose) + (heighTitle))
dialog.center = self.view.center

let me know if you have doubts

Andres Gomez
  • 458
  • 3
  • 12
  • Thanks for your help. I haven't tried doing it programmatically yet, I was expecting to achieve this from the storyboard. Guessed it could be done using constraints and changing priority in content hugging and compression. – Guz F Nov 13 '19 at 17:44
0

You need to set the tableView height dynamically, so give it two position constraints (ie centerX, centerY), a fixed width constraint, and then a height constraint set to some arbitrary constant (0). Take an outlet to the height constraint. Whenever you update the data that backs the tableview you take the min of the calculated tableview height and the superview height and set the height constraint constant to that value, then call setNeedsLayout on the tableView's superview. This way the tableview will either be the height of its content, or if the content is too big, the height of the superview and it will scroll.

tableViewHeightConstraint.constant = min(superview?.bounds.size.height ?? 0, numberOfCells * heightPerCell + headerAndFooterSize)
superview?.setNeedsLayout()
Josh Homann
  • 15,933
  • 3
  • 30
  • 33
  • Thank for your help. I already have an outlet variable for the tableview height, which I update depending on the amount of items I have. I was hoping I could achieve this using constraints in storyboard. – Guz F Nov 13 '19 at 17:46
  • If you want to do it without touching the height constraint then you don't set any size constraints. The system with then use the `intrinsicContentSize` of the view to calculate its height and width constraints. You will need to subclass `UITableView` and override `intrinsicContentSize` and you will still need to invalidate the layout whenever the number of items changes; I think its easier to just use the solution I provided above. – Josh Homann Nov 13 '19 at 18:52