I am getting an image from a URL in a tableview cell. The image view is hugging the right top and bottom of a cell in the tableview cell. To the left of the image is text. I want the text to set the height of the tableview cell automatically and I want the image to conform to the size that is set by the text. How would I do that? Right now it is working but when the image is being downloaded, the cell resizes to become much larger because it uses the large dimensions of the image. As a result the cell in the tableview gets really tall. How would I fix this?
I know the issue is because I am using a greater than or equal to constraint between two of my labels as you can see below in the screenshot. But I need that greater than or equal to constraint.
Here is what my constraints look like:
This is what they look like and what I want it to look like:
This seems to be a cell that is laid out more or less as you desire:
The first label has three lines. The second label has four lines. The third label has one line. The first label has a leading constraint and a trailing constraint to the cell content view; the other two labels have their leading and trailing edges aligned to it. There are four constraints from top to bottom, content view to first label to second label to third label to content view.
The image view has its top aligned to the first label top, its bottom aligned to the third label bottom, its leading edge constrained to the first label trailing edge, and its trailing edge constrained to the content view.
That's all.
EDIT Sorry, I omitted a piece of the puzzle. For your use case, the image view's vertical content compression resistance would need to be lower than any label's vertical hugging priority. That says: "Let the labels dictate how tall I can be." Your labels have a vertical hugging priority of 251, so 250 would do.
You have set your constraints for the 3 labels, now for the image view set equal height to your cell(90-95% should do it). So the labels control the height of the cell and then the cell controls the height of the image view.
Edit: I think that you are complicating things. All your cells will have the same height(title,preview, source of 3,4,1 lines respectively), let them set the height, you don't need content hugging priority with the way i am suggesting.
I would use equal widths to set the width for all the items in your cell, the i would set the horizontal centers, for the spacing between constraints you can either use top-bottom constraints or set vertical centers and you are done.
Bare in mind that top-bottom-trailing-leading are NOT always the best choice, sometimes (like this one) can cause headache.
Related
I have been facing issues horizontally aligning two UILabel and one UIImageView like this:
First label has variable width, can be truncated if long. Second label has fixed width, it should always be aligned to right of UIImageView. It should never go off screen. UIImageView is aligned to right of first label.
I have tried embedding them in horizontal UIStackView but the image + second label always aligns to end of cell. Got the same issue when trying without UIStackView.
Please help.
You can embed both label and horizontal StackView into another horizontal stack view. Then, you'd need to set the dynamic width Label's Content Compression Resistance Priority (you can find this property at the bottom of the Size Inspector), to be smaller in order for it to shrink.
Then on the container StackView (the one that contains all views), you'd need to set constrains to top, bottom, leading to 0 to the superview and the trailing to be greater than or equal to 0, for it to not take all space of the superview, but at the same time not get offset if the content is too wide.
I hope that is clear enough!
I have a simple UITableViewCell that contains UIImageView and 3 UILabel's. Here, I provide a normal look of the cell to understand the problem deeply:
As you noticed, the description label can be long, so I set numberOfLines to 0. But the problem occurs when that description is empty or small. Cells start to overlap each other. Here is how it looks when the description is empty or small:
If you noticed, pictures overlap each other. The constraints I gave to views are the following:
UIImageView: Leading to superview, width and height, center vertically
BookName(bold label on top): top and trailing to superview, leading to UIImageView
AuthorName(orange label): top to BookName,trailing to superview, leading to UIImageView
Description(gray label): trailing and bottom to superview, top to AuthorName and leading to UIImageView(book image)
I also provided Content Hugging and Compression Resistance Priorities. I provided them only for UILabel's. I set the smallest for description label in order to it grow and shrink.
What I've done to solve the problem?
I realized that if a description is empty, the cell becomes smaller. In other words, labels decide the size of the cell. Also, considering the fact that UIImageView only gets centered vertically, I thought that my constraints are incorrect. So, I decided to get rid of centering vertically the UIImageView. I set top, leading, width and height constraints only for UIImageView. Other constraints were the same as above. But it didn't help, here is the result:
As you see, UIImageView gets out of cell boundary. I thought that it happens because I don't provide bottom constraint for UIImageView. But I provide it for description. So, the next try was actually providing that bottom constraint. So, I provided top, left, bottom and width constraints for UIImageView. I left other constraints the same. Initially, the result was surprising to me. Here is how cells look when there is no description:
Seems like, everything is good(anyway, the image is too small, it tries to fit cell size, that is controlled by labels), but after scrolling UITableView, cells are changing their sizes and somehow updates their constraints. Here is what happened:
I also tried to set estimatedRowHeight and automatic dimension, but it didn't help and I don't think that the problem is solved in this way. So, any help is appreciated.
Keep constraints on the Image view as leading to superview, width, height, vertically centered. Keeps constraints on book name and author label as is. Now On the detail label put constraint as top to author label, trailing to superview, leading or left to image view, bottom to superview. For bottom to superview constraint on detail label change relation to greater than or equal to in Attributes inspector. Change constant to a value you need.I suggest increasing the constant and testing till you get the desired result. Start with something around 20 or 30 and test and then increment value to something else till you get the effect you want. At some value of this constant you will get the effect.
Hope this helps.
NOTE: This is assuming that your Book name label and the author label at least have some text. It can fail on other devices, so also use size classes to set different constraints
I have a cell in which I place four buttons and four labels. Each button gets assigned a picture with width 50 and height 50. Furthermore, all buttons have a corresponding label describing what they're intended for.
My objective is to have the buttons and labels resize to keep the buttons' and labels' aspect ration intact while the screen dimension changes on different devices. I have been playing with auto layout changing the hugging and compression to achieve this but haven't been successful yet. Any help would be much appreciated...
I think you should take a look at a UIStackView, because this seems exactly as a use case for stack. Just put each pair button/label in a stack, and then all four pairs into a horizontal stack, which you constraint to the cell itself. You should be able to handle all you need just by configuring the stack’s properties (axis, distribution, alignment, spacing).
Embed your button and label into a view. Set the width of this view equal widths to content view and change the multiplier value to 1:4. This will adjust the widths of the views according to superview. Also, set the top and bottom constraint to 0 for this view.
Provide center align y-axis constraint to button after setting the width and height constraint to 50. Set its top constraint to a value you deem fit.
Set labels's leading and trailing constraint to a value like 8. Choose center alignment for text. Also, provide top constraint to buttona nd bottom to its superview.
Copy the view and paste to create the three views and provide them equal widths constraint to the first view. Also, provide their leading, trailing, top and bottom constraints.
Here are a fast tutorial in how to achieve that:
1-
2- completion of the first Gif:
Note you can achieve the same output using a UIStackView
Please look at the ScreenShot attached for wCompact|hRegular for different screens, I am trying to make it working since hours but not getting any success. My requirement is that at the top there would be a label with some predefined margin. Although the Label content would render at the runtime, but I know the content size, so resizable label isn't needed actually I think. Now there would be three row at equal distance. In first and third row, there would be two buttons with equal height and width and in second row there would be button aligned horizontally. I have set the buttons image and text in storyboard. Control Alignment are set to Horizontal | vertical. Constraints for label are:
Pinned top space to superview, leading and trailing space equals to:8(superview), height equals:90.
Constraints for Button(View Transactions) are:
top space to label, bottom space equals to:8(New Launches Button) leading and trailing space equals to:8(superview) and 8(Place Request Button) respectively, and equal width and height for all buttons.
Looks fine for 4.7 and 5.5 But not satisfied with the output for smaller screens. As u can see resizing of buttons image not working properly(Larger space between button's image and text). One more thing is I don't wanna set the height of the label, cause it seems like a wrong practice in AutoLayout. Any help would be much appreciated.
You should set the Aspect Ratio for the Buttons, not just the equal width and height. In that case auto layout wont shrink the images.
Really you should put this into a scroll view so that if the height is too great the user can still see everything by scrolling. You should also not set static heights on labels, you should allow the intrinsic content size to apply.
Add a subview to your new scroll view. Pin the width of this subview to the width of the scroll view. Do not pin the height.
Add all of your buttons and labels to this new subview. Pin them to the edges of the view and allow the intrinsic content sizes to apply limits. Set various items to have equal widths and heights. Do not set explicit heights or widths (do everything by proportion or equality so auto layout can choose good sizes).
The idea is to resize height of the cell automatically based on few controls heights. As you can see on image above I have Top Label and Bottom Label. These two labels can have different height based on text length.
Few words about setup in storyboard.
I set number of lines to 0 for 2 described labels to allow grow their height dynamically based on given text.
For the Top Label I have next constraints:
For the Bottom Label I have next constraints:
So I we say about vertical spacing between 1000 green label and bottom label it's every time the same:
But without this spacing cell won't stretch height. How can I reduce this vertical spacing? Because there is to much spacing between "1000 green label" and bottom label in case if top label have big height because of text.
In -viewDidLoad method I set:
[self.theTableView setEstimatedRowHeight:145];
[self.theTableView setRowHeight:UITableViewAutomaticDimension];
Seems it works pretty cool sometimes with a bug described here but I don't know how to restrict that vertical spacing:
http://www.appcoda.com/self-sizing-cells/
Set the bottom label's top constraint to be >= 11.5 (or whatever its minimum spacing should be).
This will let the cell adjust that vertical spacing, depending on the other content in the cell.
Update:
In iOS 9, this would much more simply be handled by UIStackView.
A horizontal stack view would constrain (and determine the cell height based on the) two inner vertical stack views. The left vertical stack would handle the image, banner, and label layout, and the right vertical stack would handle the top label, 10000, and bottom label layout. You'd only need with 4 constraints (for the horizontal stackView to constrain it to the contentView).