Ad

Keep UIStackView To Be Positioned Exactly Below, Top UIStackView Inside A Proportional UIStackView

I have This one big CustomView, on which I have positioned one parent UIStackView to contain two UIStackViews.

Each of these UIStackView are set to contain two items each to fill equally.

The first UIStackView contains two UITextView, while the second one contains two UIImageView.

What I'm trying to aim is I'd like to make the bottom UIStackView which is the one that contains the UIImageViews to keep its position to being directly aligned below the UITextView from the top that has the highest height.

I want it to be just like that no matter how long the UITextView height grows.

Here is a screenshot of my CustomView.xib. CustomView.xib

It should look into something like this:

Goal view

Or like this:

or

Ad

Answer

You are close to what you want - just a few changes...

Stack Views are great, except they don't always behave well when designing them in Storyboard / Interface Builder. In this case, to get your desired result, the Text Views must have Scrolling disabled. Unfortunately, IB goes crazy when you do that.

So, you have to start with Scrolling enabled while designing your view, and then disable it via code when your view loads.

For your "parent" vertical UIStackView, constrain it to leading, top and trailing edges - no bottom or height constraint. Set it to Alignment: Fill, Distribution: Fill, and, so you have a little vertical buffer between the text and images, Spacing: 10.

The horizontal UIStackView containing your text views should be Alignment: Fill, Distribution: Fill Equally, and Spacing: 8.

The horizontal UIStackView containing your image views should be Alignment: Top, Distribution: Fill Equally, and Spacing: 8. Give each image view an appropriate Aspect Ratio constraint - in the image below, the images are 200x300 pixels, so I set the ratio to 2:3.

IB will also complain that the stack view needs a constraint for Y position or height. This is not really correct, but IB is failing us here. So, give the left-side text view a Height constraint - doesn't really matter what you use (I used a Height of 160). The key is to set the Priority on that constraint to Low (250). That will hold it in place and satisfy IB during design, but will not prevent the text view from auto-sizing to its content.

Your storyboard should now look like this (I set the view background to Blue so we can see the layout):

enter image description here

Now, in your view controller code, you need this:

class StackTVViewController: UIViewController {

    @IBOutlet var textViewLeft: UITextView!
    @IBOutlet var textViewRight: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        textViewLeft.isScrollEnabled = false
        textViewRight.isScrollEnabled = false

    }

}

When you run the app, you will see this result: enter image description here

Now, add two more lines in viewDidLoad() to change the text in the text views:

class StackTVViewController: UIViewController {

    @IBOutlet var textViewLeft: UITextView!
    @IBOutlet var textViewRight: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        textViewLeft.isScrollEnabled = false
        textViewRight.isScrollEnabled = false

        textViewLeft.text = "The left-side text field now has short text."
        textViewRight.text = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
    }

}

and, if you've set the constraints correctly, you'll see this: enter image description here

Note: At this point, you can even edit the text views, and their heights will auto-adjust when you add / delete enough text to change the line wrapping!

Ad
source: stackoverflow.com
Ad