UITableViewCell dynamic constraints - ios

I am making filling a UITableView with custom cells of dynamic heights. I am using the methodology as described here.
For the purposes of simplicity, say my cell contains 2 UILabels as shown below.
The purple UILabel will remain the same height for all cells in the UITableView. In this case, the purple UILabel is taller than the green UILabel. I would like the constraint between the bottom of the purple UILabel and the bottom of the contentView to be 8.
However, there is a second scenario that is possible as shown below.
In this case, the purple UILabel is still the same size as the first case (even though it looks smaller, but since the overall cell height is larger, relatively, it looks smaller), however the green UILabel is much larger. In this case, I would like the constraint between the bottom of the green UILabel and the bottom of the contentView to be 8.
Now my dilemma is that I can set either one or the other (I am using storyboard). But I cannot think of a way to make both possible at the same time. My guess is that you would need to adjust constraints programmatically during runtime depending on the size of the green UILabel.
Any thoughts?
I am using XCode 6.1.1 in Swift.
Thank you.

If the purple label is always the same height, then you should just set the height constraint of the element, rather than setting its bottom constraint to superview as 8.
For the green element, perhaps you could select both that element and the contentview and set them as having equal heights from the "add new constraint" pane at the bottom of the storyboard window. Then, select that constraint and edit its multiplier value in the attributes inspector to some value less than 1. That would make the element's height always be some percentage of the parent view's height. You could tweak that around until it gets you close to the desired 8px from the view below it.

Related

Create UITableViewCell constraints to match with built-in cells and avoid "fixed width constraints my cause clipping."

In my UITableViews I have a mixture of built-in cells and custom cells that mimic the look of built-in cells. For example, I use Left Detail Cell UITableViewCells as well as custom cells that also LOOK like a Left Detail Cell but have custom elements (like a left UILabel, but a textfield instead of the right UILabel and maybe other elements like a checkmark image to let the user know when they have entered valid info).
I originally set up the constraints on my custom cells so that blue left-side label would have a width constraint = 91 because that is what the built-in cell's label's width was.
However, for the last few versions of Xcode, it has been complaining at me about "Fixed width constraints may cause clipping."
I've seen all of the myriad Stack Overflow posts telling me to just make my constraint <= or >=, but that does NOT do what I want. I don't want those labels to get bigger, because then the various rows will not have a consistent width on those left detail labels. The screenshot below wouldn't have a consistent layout from row to row.
So, how can I set my constraints on that left detail UILabel so that it will match with the built-in Left Detail Cell's sizing behaviors without getting that stupid warning clogging up my build results?
I tried setting a proportional width on the label, but when I rotate the device my label gets much wider while the built-in Left Detail cell's detail label stays the same width and my UI looks janky because they aren't lined up anymore.
I tried making my fixed width constraint a lower priority (750) and adding a second <= constraint at priority 1000, but then it just complained about both constraints.
Example below:

How to set a UILabel as a percentage of the width of the UICell with autolayout

I'm wondering how to set a UILabel's width expressed as a % of the Cell's total width? I'm using AutoLayout. Normally I would click on the label and set the EqualsWidth to a parentView and then adjust the multiplier so I set the width as a % of the parentWidth. But using InterfaceBuilder that option does not seem to be available within the Cell.
However I'm wondering maybe it has something to do with setting the preferred Width: I'm using ios8+ and have read that implicit widths are not available for ios8?
What I am hoping to achieve is that Label 1 and Label 3 are both 15% the width of the Cell and Label 2 has leading and trailing edges pinned to UIImageView and Label 3 that will allow it to grow and shrink depending on the width of the device.
Steps you should do to achieve your goal of setting percentage width of any subview inside cell:
Add UIView to your cell and pin it to every edge - we have to add custom container view in order to be able to add "Widths equally" pin later on.
Add UILabel to previously added UIView container. Lets say we want to add left side label, so add 3 pins to it: left, top, bottom.
You can see now that you have error in your constraint setup. So lets fix it and add "Widths equally" pin. Select 2 views in View Controller Scene menu - the container and the label. Go to XcodeMenu/Editor/Pin/ and select "Widths equally". Now you should see no errors in you constraints setup and the label should have same size as the container. (Please note that sometimes you have to refresh frames of your views after setting constraints, so if you see "yellow" warning icon don't be afraid and just click on it).
Now if you have all your constraints we need to set actual percentage value. Open tab Size Inspector, click "Edit" title on constraint added in step 3. and change Multiplier value to 0.15 (15%).
Please note that, if you would add label using same technique but for right side, then you would need to set Multiplier value to 6.66 (= 1.00 / 0.15).
Cheers!
You can set width constraint and then create an IBOutlet for that in UITableView cell and change constraint.constant value in layoutSubView method of tableViewCell

Truncate UILabel before it runs into another UILabel dynamically

Basically, I have this situation:
Two UILabels in a UITableViewCell. They're both constrained to the top of the cell. One is constrained to the left of the cell, and one is constrained to the right of the cell.
There exists a change that the UILabel on the left can run into the UILabel on the right. Is there anyway to truncate the text x points before it gets to the UILabel on the right?
Right now, I handle this by giving the UILabel on the left an explicit width that ensures it will truncate before reaching the UILabel, but the explicit width is not dynamic based on screen size. If there is a larger screen size, it might not need to be truncated. I'm new to iOS development and am not sure how to do this.
The best way to achieve this is in auto-layout. Make sure the label on the right is a fixed size, you can even change it programatically if you need to accommodate to screen size. But the thing is this one needs a width constraint. The label on the left does not have a width constraint, instead do a horizontal spacing in front of it to the cell border and from it's trailing end to the start of the label view on the right. It will widen and shrink to fit the size that's left for it.

Applying autoLayout constraints to multiple objects

I am playing with autoLayout constraints in iOS
My use case is this way,
I will better explain with images
I am using a custom cell for UITableViewCell, through autolayout I have set constraints for text and divider line below and they obey autolayout constraints. Now you can see the yellow vertical strip on the left.
I have not set any constraints for it, so when the cell height is normal, it covers the whole cell, but when cell height increases, it doesnt increase and fill the whole cell. I am not able to make its height flexible w.r.t to cell.
I want to expand the yellow strip to cover the whole cell.
So how I can achieve this.
You can make height of yellow strip flexible by setting 2 constraints.
Set both top space and bottom space to container (cell's content view) to 0.
Ensure there is no constant height constraint for it.
You need to set constraints to the yellow view. By default it would apply its own constraints at runtime.
To the yellow view add TOP , BOTTOM , LEADING , and TRAILING constraint. DO NOT ADD A HEIGHT constraint.
Make sure the TOP and BOTTOM constraints of the yellow view are pinned to the cell's content view.
Let me know if it works.
Cheers

Why when using self-sizing cells in iOS 8 does the constraint to the bottom of the cell have to be "greater than/equal" or use vertical hugging?

I'm trying to use Auto Layout to take advantage of the self-sizing UITableViewCells.
I have one UILabel at the top of the cell and another beneath it. I set the top constraints to be pinned to the top, left and right, and the bottom to be pinned to the top left and right of the upper label.
Now as I go to set the bottom label's final constraint (its distance from the bottom) I set it to 10pt from the bottom of the cell. However this sparks a bunch of Auto Layout complaints. It says I have to make one of the labels have a higher vertical hugging priority. Why is this?
And in the WWDC video, the engineer sets the bottom one to be greater than or equal, instead of just equal. This seems like a poor solution at least in my case, because I never want it to be greater than what I set.
The IB issue you are seeing is due to the fact that the content that you currently have in the labels and all your constraints doesn't fit the UITableViewCell height (it doesn't autosize in IB yet). The autosizing happens at runtime, and setting it to greater than or equal is fine as the code autosizing will find the smallest size that acceptably fits all your content.

Resources