Swift autolayout, setting constraints for a container view - swift

I am creating a simple app for storing some permanent values and am stuck trying to get the layout how I want. I have done some basic autolayout tutorials, but I can't seem to condense this question into Google searchable format.
I am trying to set constraints for a Container View, which I want to be
centered horizontally, and
a set number of pixels from the item above it (actually, I'd love it to be a % of the screen down from the next element up, but I'm new to layouts).
For the other items in the View, I am able to set just these 2 constraints, and everything is blue.
Layout of Label
When I apply the same constraints to this Container View, the constraints are Red, and the Container View does not appear correctly when I run the app.
Layout of Container View
Is it the case that I need to learn a lot more about Container Views or Autolayout, or is it something simple and different about this particular view/element?
Thank you for any feedback.

UILabels' intristic size vary from the length of the text they contain.
Since a container view does not have such a thing, you should set up leading/trailing constraints or a width and a center constraint for it.
I would recommend to also do this for the labels, since they can easily be too long and be partially hidden this way.

Related

How to resize an NSImageView in an NSStackView?

I'm working on a project where I want the following in an NSTableViewCell:
Image
Text
Subtitle text
The NSTableView is in a window which the user can expand or contract. When the window expands and contracts, the text wraps as needed.
That much is working.
When it comes to the image view, I can't get the thing to resize at all. I don't understand how the text automatically wraps, but images don't automatically scale. I've been working on iOS so long that I might have missed something in how stack views differ between iOS and macOS, but I never had this problem in iOS.
I don't have much code because the text wraps properly without any code at all, so instead I posted a minimal project showing the problem on Github:
NSImageTableViewTest
Some things I tried:
I have to set the width/height of the image view, or the text won't wrap. It seems to me that the reason why is that if I keep the image view unbound, the table view starts at the width of the image.
I tried setting the leading and bottom constraints of the image view to no avail.
I tried setting the constraints of the NSStackView, but that doesn't help constrain the frame of the image view.
Question: do I have to change the frame of the image view in code? I did try that, to no avail.
At this point, I'm stumped and I'm sure the fix is something easy that I overlooked.
Thanks.
The image view doesn't shrink because the default Content Compression Resistance Priority is too high. Set the Content Compression Resistance Priority to (a bit lower than) "Low (250)".

Combine text and buttons in scroll rect

I'm attempting to create a scrollable UI object that has 2 sections with one on top of the other: a text section and a button list section. My main problem is that the text and list of buttons change in size depending on what content the player is viewing.
It seems that just throwing the text and buttons into an empty UI object doesn't work, because the empty game object does not take on the size of its children, and since the empty object does not have its own size, scrolling through its contents is not possible.
Is there maybe an element that I am not aware of that could help me out?
Here's the setup I use for Scroll. It seems you are missing the third object, the content object. It is what decides the physical size of your content size using a Content Size Fitter and a Layout Group. I decided to include the entire setup just in case you are missing something else.
Parent Object (Mask OR Rect Mask 2D) - Object that is the visual bounds of your UI
-> Scroll Object (ScrollRect) - Actual scroll component that drives the UI scroll
-> Content Object (Horizontal OR Vertical Layout Group AND Content Size Fitter) - Is the parent of your actual data in your scroll
To explain this a bit better, the Mask is used when you have a nonrectangular asset that you still want to be your max viewing bounds. Anything outside of this Mask will not be rendered. A Mask is more expensive than a Rect Mask 2D, so if your viewport is a square or rectangle, then use the 2D component.
The Scroll Rect is the driver of the scrolling of UI elements in Unity. Make sure to check the box if it is horizontal or vertical. I assume in your use case you are using vertical. Make sure to set the Content field to be the child of this object and the Viewport to be the parent (the mask).
The Content Object has two components on it. The first being the Content Size Fitter which will force this object to be the size of its content. If your scroll is a vertical scroll, set the Vertical Fit to Preferred Size and leave the Horizontal Fit to be Unconstrained size. If it is the opposite, then set the opposite of what I just said. The other component on this object is a Horizontal Layout Group OR a Vertical Layout Group. The difference being which direction your scroll is. The checkboxes in the settings of this object matter quite a bit. Check out the docs on what each one does.
If you attach the components as I specified and set the proper settings on the layout group, you should be able to have as many dynamic objects with variable size swapping between text and buttons.
If you have any other questions let me know. UI can be a bit daunting at first but once you figure it out, it gets much easier.
Edit:
To achieve an object that can change size with a text object and a button, you will need to use a combination of content size fitters and layout groups.
Here is an example hierarchy
Here is the result
Using a combination of the layout groups and content fitters forces the container the text is in to be the size it needs to be. If you are making these assets static meaning none of it is data-driven at runtime, then this should work right away. If you are changing this data at runtime, you will need to use LayoutRebuilder on the parent objects to assure that the layouts rebuild properly. Let me know if you have questions.

How do I set specific y position, width and height without diving into code?

A designer I'm working with wants to have a UIImageView be at a specific y position, with a specific width/height depending on the iphone size. I've done research and I haven't been able to find anything online that allows me to do so with constraints on the story board. I want to avoid having to use code because throughout the rest of the app there are a lot of similar situations. In the past I've made different storyboards for each phone size to accommodate for the specificity our clients request, but I want to avoid doing this because it feels like bad practice. Is this even possible?
This can be completely handled in the Interface Builder. Follow the steps below.
1) Add your UIImageView to the ViewController
2) Set constraints for Width, Height, Vertically Align and Horizontally Align
3) You can adjust the Y position in the Size Inspector of the view.
4) Now switch to Assistant Editor and choose 'Preview' and add different screen sizes to see the auto layout in action.
All of this will set a static image size of 250x200, horizontally centered, and vertically at 1/4 of the screen height.
Little-known capability of constraints are that you can set view positions, or in your case sizes, by way of ratios against other views.
With just your image view selected, the tie-fighter :) constraints button lets you specify absolute positions & sizes: do that to set your desired y-position. But then select both your image view and its enclosing parent view, then the pop up for that same button now enables the equal height/width buttons. Add those constraints and then edit the constraint to change the 1:1 ratio to whatever ratio you need.
Excuse my lack of screenshots, posting from my phone.

How to set which view expands in a UIStackView?

I was just experimenting with UIStackView. In this quiz app i have different sized imaged, so i want the image to fill the space between the top button and the question text at the top. The buttons have constraints on them so they should be any size under 50px. As of now the top button is the one getting auto increased size, but that seems kinda random.
According to what I understand you have all the items inside a vertical UIstack. The images have different sizes so the available space for the buttons will changes based on the size of the image. I suggest that you add constraints to all buttons to be equal in height. This way they will re-size based on the available space but they will all have the same height.

AutoLayout to adjust image size proportional to 50%

I have read this post and I have tried with many examples but i could not put two images one beside the other, each one with a width 50% and at the same time that this images maintain their aspect ratio. I do not understand what restrictions need to.
I have this:
In the image you can see the viewcontroller structure, 2 imageview and the constraints.
Please I need help, at least one similar example. Thanks.
I can see you have missing constraints on your scene, so that could be an issue.
I would put the UIImageViews in a container view pinned to your main view, making sure there are no missing constraints. The benefit of this is in debugging - you can give it a different BG colour and make sure it's resizing itself properly on the simulator/device. I found that putting the image views inside this helps enormously.
Then you need to specify Aspect Ratio constraints on your image views, and also make them equal widths and heights. Add some small constant horizontal spacing between your image views and top/leading/trailing to the container view, and let auto-layout decide the optimal image sizes.
I've included a screenshot of my storyboard:-
This renders like so:-