1

I'm trying to add a subview that would always have the same size as its parent, so that it would always resize if the parent size changes.

I was thinking about adding (top, bottom, leading, trailing) constraints from the code.

When I add the subview, this code is executed :

subview.frame = parent.frame
subview.translatesAutoresizingMaskIntoConstraints = false
subview.leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true
subview.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true
subview.topAnchor.constraint(equalTo: parent.topAnchor).isActive = true
subview.bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true

But the subview size stays at 0, and is displayed at the top left of the screen. I don't understand why it's size is zero since I set it's frame, and also because it has all the constraints to set its size.

Inspector view :

Note : The parent is on the left, the subview (LoaderView) is on the right

parent view subview

Xys
  • 8,486
  • 2
  • 38
  • 56
  • Are any of these views a scrollView (I'm assuming so since I see the message "scrollable content size is ambiguous")? Do you have any autolayout warnings in your storyboard or xib? Why are you adding constraints in your storyboard and in code? You only need to do it in one place. Lastly, you don't need to be concerned with setting the subview frame if you are using autolayout. – Rob C Apr 20 '20 at 09:27
  • @Rob Thanks for your answer. I'm not adding constraints in the storyboard, because I add the subview programmatically. And yep you're right I shouldn't need to set the frame – Xys Apr 20 '20 at 09:40
  • @Rob Those are screenshots of the view hierarchy debugger – I initially thought they were of the storyboard, too, heh. – TylerP Apr 20 '20 at 09:43

1 Answers1

1

Your parent view seems to be a scroll view, and it is missing the constraints that tell it what its scrollable content size is (note the warning in your first screenshot). Since nothing is defining the content size, the scrollable area size is therefore just zero.

I'm not sure what constraints you need exactly as that depends on the details of your situation, but in order to at least see your subview you could add (for example) equal-width and equal-height constraints to your subview and its parent view (the scroll view):

NSLayoutConstraint.activate([
    subview.widthAnchor.constraint(equalTo: parent.widthAnchor),
    subview.heightAnchor.constraint(equalTo: parent.heightAnchor)
])

This defines the scrollable area as being equal in width and height to the scroll view's frame. However, if you do this then there won't really be any kind of scrolling other than the bouncing behavior when you try to scroll beyond the scrollable area (if that's turned on for this scroll view).

You could instead change the height anchor to be equal to some constant, just to allow for some actual scrolling:

NSLayoutConstraint.activate([
    subview.widthAnchor.constraint(equalTo: parent.widthAnchor),
    subview.heightAnchor.constraint(equalToConstant: 2000) // just some arbitrary amount for demonstration purposes
])

This makes the scrollable height equal to 2000 points, regardless of the height of the scroll view's frame.

Or, if you want the scrollable area to be some multiple of the scroll view's frame height, you could set a multiplier on the height anchor:

NSLayoutConstraint.activate([
    subview.widthAnchor.constraint(equalTo: parent.widthAnchor),
    subview.heightAnchor.constraint(equalTo: parent.heightAnchor, multiplier: 3)
])

This makes the scrollable height equal to three times the height of the scroll view's frame.

And if you want a horizontally-scrolling scroll view, just change the widthAnchor instead of the heightAnchor like I've done above. Or if you want a 2D-scrollable area that lets you pan around both vertically and horizontally, then change both.

TylerP
  • 9,600
  • 4
  • 39
  • 43
  • Thanks a lot, it works perfectly ! But I still find it weird that it works with the width and height constraint but not with the bottom / trailing though ? I get the point that since it's a scrollable view the height and width are not defined, but then why does it work with the width constraint ? Or maybe I am missing something ? – Xys Apr 20 '20 at 10:15
  • You need to tell the scrollview how big of a scrollable area it has. It's not enough to just give your subview top, leading, bottom, and trailing constraints (which are constrained to the _scrollable area_, not the scrollview's _frame_ – it's important to understand the difference), as these constraints alone don't give the scrollview enough information to determine the scrollable area's width and height. Hopefully that makes sense! – TylerP Apr 20 '20 at 10:21
  • Thanks ! The idea is that I wanted to display a custom loading view on top of the collection view while I'm loading its content ;) – Xys Apr 20 '20 at 11:33