Auto Layout for complex view in Table View Cell - ios

I know this might not be the best question but I really need to a starting point:
If I wanted to create a layout as the one below (using auto layout):
What I tried was:
Put the Three zeros in a horizontal stack view
Then put the three labels (posts, followers, following) in a horizontal stack view.
Then put those two horizontal stack views above into a vertical stack view.
Then I added that gray button below the (posts, followers, following) labels into the vertical stack view created right above. So in the end I had one vertical stack view consisting of two horizontal stack views and the gray button.
Finally I added the image to the left in the vertical stack view created in the above step which made a final horizontal stack view. This step ruined my layout completely. Made the image like 500 width which made the stack view go off the screen. So I set layout constraints on the very last horizontal stack containing the image, gray button, and two horizontal stack view to Bottom Space: 140, Top space 10, Leading Space 20, Trailing space 20. (I didn't touch the stack views inside this final stack view. I only put layouts on the main horizontal stack view created in this step).
After 4bar suggestions:
Please note I have not touched the first name, facebook.com, or bio label at the bottom.

If you have not set the distribution mode for your outermost horizontal stack view, it will default to UIStackViewDistributionFill, in which case the arranged subviews will stretch to fill the whole width according to their hugging priority. Increase the content hugging priority on the image view (say, to 251) to prevent it from stretching. Also, if the image size is larger than the space you'd like to devote to it, you may also need to set additional width or height constraints on the image to override its intrinsic size.
The main thing to understand is that UIStackView's size is driven by the intrinsic sizes of its arranged subviews, plus spacing. In Fill mode, if too much space is available, content hugging priorities are used to determine which view to stretch; if too little space is available, compression resistance priorities are used to determine which view to compress.

As shown below, You need to set the width of the stackView containing the image.

If you want the image to look like a square, you have to pin the width and height of the image to the same value. Then set Mode to AspectFit so that image won't look stretched.
Pin the width of the labels like 'posts'. So that they will show the entire text.

Related

How do I ensure UILabel only takes the space it requires, without extra padding?

I have a peculiar issue when dealing with my label in Vertical, then horizontal stack view.
The horizontal stack view is supposed to be of a dynamic height based on the label's contents. I've tried other solutions mentioned before, such as embedding the label (and image which is also in the horizontal stack view) in separate UIViews and pinning the labels to the edges.
The issue is, when the label is set to 0 - the label grows beyond what it requires, adding padding above and below the label.
I did verify this wasn't an issue with constraints from where the Stack View begins below the imageView, as the warning label correctly floats upwards when aligning the stackview to "top", but the label still remains centered.
Everything has been done in the storyboards without code.
Take a look at the images, maybe someone can help me out and recognise how I can resolve this issue.
Desired Effect
What occurs upon running the application
Verifying that the stack view is correctly pinned to the image view by aligning top
Constraints involved
The second stackview in the hierarchy at the bottom is just to fill the empty space during the designing phase. I don't think that would be causing the issue.
I would guess that actually your second stackView at the bottom is also the part of your problem. If you pinned the vertical stack view to the bottom of the image (TOP constraint) but you also pinned it to the bottom of the screen (BOTTOM constraint), your vertical stack view tries to strech it's content. That's the reason why the label has the extra space.
What you can do: get rid of that bottom constraint (don't give vertical stackView bottom constraint) or maybe better set vertical content hugging priority of warning label to greater value.
Here, the warning UILabel is occupying the remaining available space, try adding an empty UIView in the second stack view which you kept for the later stage of the development. This will act like a spacer view.
Also, don't forget to call warningLabel.sizeToFit() inside viewDidLoad()
You can achieve this by calling yourLabel.sizeToFit()
Above will dynamically adjust the height of the label based on the amount of space your text occupies.

iOS how to set Stack-view width Dynamically According to Label Content size Height & Width

How can I set stackView's width according to label's content width?
This can be very easily implemented in a stack view. All you have to do is fix the position of the stack view in the superview by giving contstraints of any two adjacent edges of the stack view(say, leading and top in your case) with respect to its superview.
You don't have to give constraints in between the labels separately like vertical spacing for a vertical stack or horizontal spacing constraint for a horizontal stack(as long as you don't want to override the basic behaviour of a stack view). All this can be easily managed using the distribution and space properties of the stack view (you can find these in the attributes inspector of stack view)
I recommend going through the Apple's doc on UIStackView, particularly the section "Common Stack View Layouts". In "Define the position only" subsection it states,
You can define the stack view’s position by pinning two of its
adjacent edges to its superview. In this case, the stack view’s size
grows freely in both dimensions, based on its arranged views. This
approach is particularly useful when you want the stack view’s content
to appear at its intrinsic content size, and you want to arrange other
user interface elements relative to the stack view.
Secondly, since you are using the Stack view inside a Table View, if you are changing the label's content dynamically, after loading the Table View. Then you should call beginUpdates and endUpdates of the TableView in order to see the table size grow/shrink/adjust according to the adjusted Stack view's height/width.
If you still face any issues. Please provide more details regarding the UI you want to achieve(expected) and how it's behaving currently. That'll help in providing a more precise answer.
Hope it helps! :)

Position and size are ambiguous for “view”

I have set pin to all view but i got continuously this alert !
I have seen that this is because of height and width constraints but i didn't add height and width still i got this error !
This alert should be avoidable or not.
A UIView has no intrinsic size meaning none of your views know how large they should be and thus cannot be laid out the way you have them. You can set the height of each one to a fixed number but if you want them to scale I recommend using Equal Heights and Equal Widths and set the multiplier to the proportion of the view you want the little views to size to be. You could do this so many ways.
I am going walk you through one way that I think is the quickest(using StackViews) for my own sanity but the same logic could work with more dragging from each view.
Step 1:
Drag a Vertical StackView to the top of the storyboard. Add the following constraints. pin leading, trailing, and top =20. Then drag from the vertical stack view to the main view and choose equal heights and change the multiplier to 0.6(60% of the main view height). See image
Step 2:
Add a single horizontal stackview as an arranged Subview to our vertical stack view. Now add 3 UIViews and change the colors to desired colors. Change stack view to Alignment-Fill and Distribution-Fill Proportionately. Also add spacing=20. See Image
Step 3:
Choose your horizontal stackview that you just created in step 2 and hit Command-C to copy it. Hit Command-V to paste it. Note- If it does not paste it into the vertical stackview drag it in to the vertical stack view. Not there yet but close. See image
Step 4: Go to the vertical stack view and change it to Alignment-Fill and Distribution-(Fill Equally). Add Spacing of 20. You should now be a point that looks like this. See image
Step 5. Add a horizontal stack view below the vertical stack view and the bottom layout guide. Pin to all four sides at 20. Add three views and change the color to desired color. Change Alignment-Fill, Distribution-Fill Equally, and spacing=20.
Step 6. Adjust verticalStackView equal heights multiplier to maybe a lower number(0.5) to make it look like your view.
Step 7. Reap the rewards
The Big takeaway is that a UIView needs to know how big it is. UIStackView in this case tells the views how big they are. You could just have easily set the height and width of one of your views in your screenshot above to a percentage of the view. Then drag from that view to all of the like sized views and set equal heights/widths. That would have been more tedious and you can see why I used Stackviews for the example. Good luck.

How to center a Label with an ImageView next to it in Swift?

I am trying to have a UIImageView next to a UILabel with dynamic content. Both within a StackView.
Currently I'm using the Fill Alignment and Distribution. Changing it to one of the other options, changes the size of the ImageView (fixed Constraints to 30x30).The StackView has left and right leading Constraints of 0.
This is my current:
The is what I want:
How do I need to set up the StackView to archive my goals? Help is very appreciated.
You can try using a vertical stack view with an embedded horizontal stack view.
The first stack view has a vertical axis. Its alignment is centre and the distribution is fill (the default). This stack view has the following constraints: Trailing to superview, leading to superview and top space to top layout guide.
The second stack view contains the image view and label. Its axis is horizontal. The fill alignment and distributions are set to their default values. The spacing is set to 10 (can be changed to suit your needs). This stack view has no constraints.
The image view has a height and width constraints of 30 respectively.
The label has no constraints.
Both the image view and label have default content hugging and compression values.
If the label has longer text then then it will appear like this:
Have you tried manipulating content hugging and content compression resistance priority ? I believe these property will let you manage the length distance between both the image view and textView, and the stack view won't let you dynamically expend the textView as you enter more and more data so I think manipulating the hugging and resistance properties can give you a solution close to the required.
This can be achieved by creating a container view for the image view and the text label and then centering the container view in the original parent view.

View inside UIStackView is not resizing with AutoLayout

I have this following screen:
All of the views are inside an UIStackView. The yellow view would be circular on runtime. My issue when I run an a smaller iPhone (5S), the light blue view which contains the yellow view, will not get smaller, so the red and blue view from the bottom will shrink. I want these two and the green view to have fixed width and the light blue view to adapt height.
But for some reason it doesn't. I am sure is because of the constraints I set to the yellow view. But I can't figure out which one is the problem.
Here are the yellow view constraints:
The constraints for the other views are:
Green view: height = 64
Red and blue view: height = 50
Much appreciate if someone could take some time to look over this constraints and help me understand how to make the light blue (and yellow) to change height when screen changes.
Did you try lowering the Content Compression Resistance Priority (vertical) for the light blue and yellow views to be less than 750, and the Content Compression Resistance Priority (vertical) for the green, red and blue views to be higher than 750 (maybe even 1000 / required if that's the case?)
UPDATE
I took a look at your project. Actually, the issue doesn't seem to be with your stack views, constraints, or the DailyStatusViewController at all. Instead, the issue looks more related to the MainViewController which is embedding the Daily Status view inside a scroll view. The scroll view is both clipping to bounds, and is placed behind another container view. If you turn off clip to bounds on the scroll view, and move the container view below it to be behind it, you will see your stack views laid out correctly, but were just being clipped.
As to why they were clipped, keep in mind that your out stack view has a required height constraint of 300, while the scroll view it's being embedded in has a height constraint to 45% of the screen height. So on smaller screens, there is less than 300 points available to display the Daily Status view, and so it is being clipped. You probably want to remove the fixed height constraint from your outer stack view and instead constrain it to the edges of the root view.

Resources