UITableViewCell with two UIStackViews - ios

I'm facing a layout issue with a UITableViewCell which consists (from top to bottom) of (1)a UIStackView, (2)a UIView with a fixed height and (3)another UIStackView. In the top UIStackView I want to place a few instances of UILabel vertically, depending on some datastructure. These labels can vary in height. In the bottom UIStackView I want to place a few instances of UIButton vertically. This number also depends on some data structure.
The problem has to do with AutoLayout (at least I think it does). How would I set up the constraints in such a way, that the UITableViewCell creates both enough space for the top UIStackView and the bottom UIStackView when it needs to be placed on screen. The layout of the cell is defined in a separate XIB file.
So far I have a heightconstraint on the top UIStackView. Depending on the frameheight of the labels the height of the stackview is adjusted. But it turns out, that the height always has the same value. I know this, because I need two instances of this particular UITableViewCell in my TableView.
The bottom UIStackView does NOT have a heightconstraint and has always a correct layout.
Do I need to adjust the properties for vertical hugging/compression resistance priority?
Any help is greatly appreciated.

Maybe I misunderstood your issue, but why are you fixing the height of the top StackView if it's height is supposed to be dynamic ? You should remove this constraint and set intrinsic sizes (below "Content compression resistance priority") of both StackView to "placeholder" to keep IB happy.
The top StackView will then behave the same as the bottom one, provided you don't have other constraints issues.

Related

How to make dynamic UIStackView inside UITableViewCell?

I have following, completely ruined design after I tried to implement dynamic-vertical UIStackView inside UITableViewCell:
As you noticed, the label on top of this card is not fitting inside cell. Basically, this cell contains following UI components:
The UILabel (that one which is not fitting). Constraints: top, leading, trailing.
UIStackView(distribution&alignment fill) (it shows list of items with price). My custom view which is responsible for showing item's name and price is inserted to this stackview. Constraints: top to bottom of UILabel (that one which is not fitting), leading, trailing.
The UIView (that divider line with constant height). Constraints: height constraint, leading, trailing, top to bottom of UIStackView.
The two UILabel's (Full amount and total price. You can see it on image). Constraints: Top to bottom of divider line, leading, trailing and bottom constraints.
I set most intuitive constraints in XIB file. There are no errors or warnings. But anyway, the cell is not showing full content inside of it. I have following guesses:
This cell is not alone. I also show other custom cells that have different intrinsic heights. I think iOS doesn't understand how to calculate the height of this cell. Then, I implemented methods estimatedHeightForRowAt and heightForRowAt by returning UITableView.automaticDimension. But, anyway, it didn't help.
I think it is because of hugging or compression resistance priorities. That label is not fitting because it has equal compression resistance as other views. So, Auto Layout randomly decides which view should be ruined and just ruins that view. Ok, I set maximum compression resistance to that label and know it is fully shown. But, Auto Layout decides to destroy my UIStackView by clipping texts inside of it, even they have numberOfLines set to 0. I don't want my views to be clipped. I want them to be shown fully.
It seems serious problem. So, how can I solve it. Here is how constraints are set:

iOS 10 square UIIMageView in Stackview breaks Autolayout when hidden

I have a UITableViewCell with something I thought was a pretty straight forward layout. The main content is a UIStackView (horizontal). In it I have UIImageView and two UILabels. On the UIImageView I have 2 constraints. One is an aspect ratio of 1:1 to make it square and the other is a height constraint to 55 points. The UIStackView is pinned to all sided of the cells contentView.
Now when I don't have an UIImage to display in the UIImageView, I simply call imageView.isHidden = true and the UIStackView hides the image. At the same time, on the Console I see AutoLayout breaking. It's telling me that it cannot satisfy the height of 55 together with the width of 0.
Well makes sense because due to the aspect ratio, the UIImageView wants to have a width of 55 as well. However, on the device itself I don't see any weird glitches. It exactly behaves as I would expect it.
So the question is
Is this a bad thing and how would I solve this with the least amount of code?
By the way, I'm using a dynamic height self sizing UITableView and let AutoLayout determine the height of my cells. It might happen that the UIImageView is the only content of the cell.
It's not a bug StackView Adds constraint to it's arrangedSubviews. when you call the hide on your view which in your case is the imageView. stackView tries to set the height Constraint to 0 but the Height constraint that you have added conflicts with the one which was added by stackView.
you can change the Priority of the height constraint to something less than 1000 it will fix the conflicting issue

Disable Horizontal Scrolling of UIScrollView AutoLayout Resizable ScrollView

I have a UIScrollView which is getting resized on runtime according to some conditions. Now i used auto layout properly without using a single constraint extra or less. The first subview of scroll view has leading, trailing, top, bottom and equal width to scroll view and the height of the content view is managed by its inner content which is also changing depending on the runtime condition. Now according to my constraints my content view should not scroll horizontally as i used equal width to scrollview. But its happening. Can anyone suggest what am doing wrong? Here is the images of constraints i have used.
NOTE:- I have seen the posts on stack where this kind of question answered but my case is different.
Content UIView width should be equal to the width of UIScrollView's superview for instance, not UIScrollView itself.
In my case, I used to 'constraint to margin' option while I am adding constraint from storyboard. When I only add trailing and leading without relative to margin problem solved. I did not give any superview to my UIScrollView.

How to setup autolayout constraints properly for self-sizing cells

I've seen a lot of guides about self-sizing cells in iOS 7 and 8. Unfortunately, all of them shows very simple cases (I mean two UILabel's with same width and which placed like the first under the second and their constraints are very simple too). So I've a situation that seems to be not so much difficult but I can't resolve a problem.
I believe that it is very easy for the most of people and hope that somebody can help. The problem is that there is UITableViewCell with 3 child views inside.
Every view is UILabel. Labels placed in such order: two labels at the top of UITableViewCell with fixed size and one at the bottom with fixed width but with dynamic height. How should I setup my constraints properly to make my UITableViewCell be self-sizing?
The key to self-sizing is a vertical set of constraints that will determine the cell height. This isn't that complex, as you don't have two horizontal labels that vary in height.
Since headerLabel and dateLabel height don't vary, you only need to constrain the dynamicLabel to one of the two top labels.
In this example, we'll arbitrarily pick headerLabel to use in the vertical constraints. The spacing between the labels wasn't specified, so I'll assume it's 10. Adjust as necessary.
For your horizontal constraints, set leading and trailing space to the superview.
Your vertical constraints would simply look like "V:|-10-[headerLabel]-10-[dynamicLabel]-10-|" (and should
dynamicLabel will grow as tall as it needs, provided you set its numberOfLines to 0, and its height will end up determining the height of the cell.
Assuming the constraints are setup properly, and the storyboard cell height exactly matches the vertical height set by the constraints, you shouldn't see any storyboard warnings or errors, and should be good to go.
8.4 does address a number of issues, so you shouldn't require any specific (layoutSubViews/preferredMaxLayoutWidth/reloadData) code to work around earlier 8.x problems.
As an aside, a general tip is to pin your constraints to the superview margin, instead of the superView. This means your leading, trailing, top, and bottom constraints could be 2, instead of 10, since the margin is generally 8. This lets your white space adapt to different devices, which is a really nice touch.

UICollectionViewCell inside UITableView Cell and Auto Layout

I have anUICollectionView inside aUITableViewCell and I have some issues regarding to Auto layout.
That's the hierarchy of my views.
UITableViewCell
|
-------ContentView
|
-------MyView
|
|-----UICollectionViewCell
Until here, all views are pinned up in his superviews., e.g: trailing space=0, leading space=0, top space=0, bottom space 0.
The height of myUICollectionViewCell is dynamic, based on the number of itens, which I draw usingUICollectionViewLayout. So it has a height constraint which is >= 100.
After the Items are in place, I call one delegate to update that height constraint, so myUITableView is able to calculate the right height for theUITableViewCell.
Even though this are working fine, sometimes I get the auto layout error above.
How can I avoid this?
The cell's contentView has a fixed height (44). That's causing the occasional conflict between the storyboard, and Auto Layout's derived height.
Self-sizing is the best way to go. What you want to do is to get your "collection view" to determine its intrinsic size, so Auto Layout can automatically handle the variable cell height for you.
See the detailed walkthrough by smileyborg in his answer to Using Auto Layout in UITableView for dynamic cell layouts & variable row heights.
He uses labels but the principle is the same. The cell asks its contentView to lay itself out. The contentView asks the label to lay itself out. The label determines its height. Auto Layout determines the contentView's height, based on the label's constraints, and the cell determines its height, based on the contentView's height. The point is that the label doesn't have a height constraint, and your "collection View" would no longer need one either.
Once you adopt self-sizing, it eliminates a lot of code (and size constraints), as containers manage their size, and constraints simply handle spacing.

Resources