Views are Horizontally and Vertically Ambiguous with complex layout

前端 未结 2 1772
-上瘾入骨i
-上瘾入骨i 2021-02-10 09:44

I have a UIViewController on my storyboard that has 2 subviews side-to-side horizontally. I added constraints to fix the leading and trailing edges to a constant (

相关标签:
2条回答
  • 2021-02-10 09:56

    Vertically Ambiguous

    Okay, I think I've solved the vertical ambiguous part. I added two vertical constraints between the pink and purple views and two vertical constraints between the pink and red views. For each pair, the first constraint is that the spacing between them must be > 20 pts, and it has 1000 priority. The second constraint is that the spacing is = 20 pts, but it only has an 800 priority.

    For example, if the bottom of the purple view ends up being lower than the bottom of the red view (as it is in my first screenshot), Xcode should try to set the vertical distance between the pink and red views = 20, but it will realize that that conflicts with condition that the space between the purple and pink being >= 20. Since the >= constraint has higher priority, the = constraint will be ignored. Now, when Xcode looks at the constraint that the spacing between the purple and pink views being = 20, it checks that against the constraint that the pink and red must be separated by at least 20. Since the bottom of the red view is higher than the bottom of the purple view, the >= 20 constraint between the red and the pink still passes.

    So TL;DR, you can set up a view to have a spacing at a given value (x) from the most extreme of multiple views by giving it a >= x constraint with 1000 priority and giving it a = x constraint with <1000 priority for each view you are considering - and my vertical ambiguity problem has been solved. I do not yet have a solution for the horizontal ambiguity for all 4 of the views.

    Horizontally Ambiguous

    Okay, I got the horizontally ambiguous part fixed now as well. What it boils down to is that constraints in scroll views (and therefore table views) work differently than they do for any other kind of view. Here's what the step-by-step looks like.

    • Place the UIScrollView
    • Place a UIView into the UIScrollView to serve as a "contentView" for that scroll view
    • Add constraints to pin the contentView to all 4 corners of the scroll view AND pin it's width and height (so 6 constraints between the contentView and it's superview - 2 more than usual). Note that the width and the height can be pinned to something much larger than the normal screen size, which is probably why you are using a scroll view to begin with.
    • Add all of your other views you want in the UIScrollView (UIButtons, UILabels, etc. - I'm just going to assume UILabel from here on so I don't have to type as much, but any kind of UIView subclass will work) as subviews of the contentView, NOT directly as subviews of the UIScrollView

    With this setup, the UILabels that are given constraints to their superview will constrain to the contentView, which has a defined size, so nothing is ambiguous.

    Alternatively, if you want to fix the sizes of your UILabels (or dynamically calculate them, depending on the functionality of your app) and let the contentView expand to hold them:

    • Place the UIScrollView
    • Place a UIView into the UIScrollView to serve as a "contentView" for that scroll view
    • Add constraints to pin the contentView to all 4 corners of the scroll view AND pin it's width and height
    • create an outlet for the width constraints on the contentView (let's say we name it contentViewWidthConstraint)
    • place the UILabels
    • fix the sizes of the UILabels
    • create an outlet for the width constraints on the UILabels

    Then in the code for viewWillLayoutSubviews

    • add up the widths of all of the UILabels and any gaps you want between them (as a CGFloat, which I'll call totalWidth)
    • set contentViewWidthConstraint.constant = totalWidth

    And you're good to go! Note that I assumed you were setting the width in most of this example, but it should be just as applicable to height.

    0 讨论(0)
  • 2021-02-10 10:11

    The problem is that many different widths of the two views will satisfy the constraints that you've set up. Here are two examples (I drew the shapes stacked vertically to make it easier to see the overlap example):

    Ambiguity example

    You can add a horizontal space constraint with a value of 0.

    Screenshot

    0 讨论(0)
提交回复
热议问题