Self Sizing UITableViewCells with UITextViews - ios

I am using sizing classes to make two separate layouts for a UITableViewCell. I am using IB to create all of the constraints. I have four UILabels and one UITextView in the cell. The wAny, hAny class works perfectly.
The hCompact, wRegular class was getting a broken vertical constraint, which I fixed by giving the vertical spacing constraint from the UITextView to the content view a 999 priority instead of 1000.
An issue still exists that causes the UITextView to collapse all the way (or the cell to be sized such that it covers the UITextView completely) when the cells are first presented. All out-of-view cells render fine when they come into view, and the original cells also render appropriately when they come back into view after going out of view.
I want to be able to use self-sizing cells and have the UITextView render correctly upon load. It would also be nice to know why I had to set the priority of the constraint to 999 to fix that layout warning at run-time.
This is only occurring on my hCompact, wRegular class which, in my opinion, has a less vertically complex set of constraints set up than the other sizing class. I have included an image of the UITextView selected and showing the constraints on the right. I gave the UITextView a lime background for debugging. As you can see, it looks rather odd in IB. I will provide any other info as requested.

Related

Design Self-Sizing UITableViewCell using .xib, cell doesn't adjust itself in interface builder

I'm trying to use .xib file to design a self-sizing UITableViewCell. However, the cell doesn't adjust it's height according to it's content subviews. I have to adjust cell manually. If the cell is too large, a subview will be stretched to fill the cell. And if the cell is too small, there will be some constraint error alert by interface builder.
The UI is correct when running, but is broken when designing.
When using a .storyboard file to design a self-sizing cell, it works great. The cell can grow or shrink automatically.
Is this a limitation of the .xib file? Or did I miss something?
If you set constraints properly, the UILabel will be set its height and width as per the set constrains and its content.
All you need to do is...
For the first label you need to set Leading, top and trailing constraint
For the second label you need to set Leading, top constraint with the bottom of first constraint, and finally trailing and bottom constraint to the superview.
Do not forgot to set the number of line equal to zero & Line break mode to Word Wrap in the Attribute Inspector.
Also need to set the following
We could consider it a "limitation" ... but it's more a matter of "by design."
When laying out UI elements in Storyboard (including a Prototype Cell), Interface Builder (IB) does a lot of additional work. For an obvious example, you can change the Orientation and your prototype cell will automatically expand its width.
When developing a XIB, though, IB doesn't change your root view's size on its own. Think of it as IB saying "you're designing a XIB, you know what you're doing and you know exactly what you want."
While it's generally a good idea to follow IB's advice and get rid of any "constraint error alerts" it's not required.
There are legitimate instances when designing a cell (or other view) in a XIB where you cannot eliminate all constraint warnings. For example, if I put a UIScrollView in my cell XIB, but the scroll view will not have any content until run-time, IB will tell me it has "Ambiguous scrollable content size." In this case, I know my constraints are correct, and I know the content size won't be defined until I add and constrain subviews at run-time... so I can ignore the warning.
If you find it a hassle to manually resize the cell, but not see constraint warnings, you can (for this example) if your bottom-most constraint is Zero, give it a Priority of 999, or set it to >= 0 ... or, change the Ambiguity option to either:
or:
First set top, left, right constraints of first label and bottom, top, right, left constraints of second label with cell.
Set Lines of labels to 0 then it will work as you are expecting.

UITableView resize cell based on content

Hi I need help with understanding how to resize cell based on its content.
So first of all of course I found many links:
iOS: Multi-line UILabel in Auto Layout
https://www.youtube.com/watch?v=CkvZEJ7dIfw
https://github.com/williamhqs/GSTableViewDynamicHeight
As we said about git example (last link) I can't understand how to change some label and make it works. For example if I delete UILabel and create new one and bind it with content property (content - it is IBOutlet property of bottom label). I seems lost some setting and cell won't stretch.
So I think I don't know to much understanding how to do it.
What I want to understand:
How to setup auto layouts in the storyboard or programmatically.
Which thing I should handle programmatically to make it done.
How the preferred size affects on label. Do we need every time use bonds of superview as a preferred size?
Also in the git example we have one label that changes itself size. What if we have 2 UILabels with dynamic content how to setup it?
If you have some links or videos please drop them here, because I really stuck. Thank you!
I know it's duplicated question but I can't understand how to setup it.
To make Self Sizing Cells works there is three steps:
Setup correctly the constraints of the cell (most important the top and bottom constraints)
Specify the estimatedRowHeight of your table view
Set the rowHeight of your table view to UITableViewAutomaticDimension
for step 2 and 3 it's so easy just add these two lines in you viewDidLoad method
tableView.estimatedRowHeight = 44.0 // or whatever you want
tableView.rowHeight = UITableViewAutomaticDimension
for step 1 which is the most important part of self sizing process
what you need to keep in mind is that "self-sizing needs to get its size from your constraints."
Basically we need to make sure that top space and bottom space constraints of our cell is correctly set up here is an example :
just two labels with the constraints top,bottom,right and left space to each other and to container (see image) the UILabels Lines property is 0 so that you allow have multiple lines
Another example from a project that I am working on:
bottom line:
The label constraints should push against the size of the table view cell and make it taller. So always check the top and bottom constraints.
Also you may run intro trouble working with UILabel with multi-lines because
The intrinsic content size of UILabel and NSTextField is ambiguous for
multi-line text.
so make sure always to setup the preferredMaxLayoutWidth property of yout label:
- (void)layoutSubviews
{
[super layoutSubviews];
self.contentLabel.preferredMaxLayoutWidth = self.contentLabel.frame.size.width;
}
for more infrmation about this issue here read :
iOS Autolayout multi line UILabel
iOS multi-line UILabel in Auto-layout
preferredMaxLayoutWidth
And for more information about Dynamic Table View Cell Height in general here is some useful resources:
UITableView Tutorial: Dynamic Table View Cell Height
Understanding Self Sizing Cells and Dynamic Type in iOS 8
Self Sizing Table View Cells
Mysteries of Auto Layout, Part 1 (wwdc 2015)
Not sure if it will apply to AutoLayout, although when laying out a cell programmatically, running "layoutIfNeeded()" fixed my cell content stretch issue.
layoutIfNeeded was ran at the end of a configure method, used to map values (view model) to UI objects (views)

iOS and interface builder: misplaced view (e.g. UITableViewCell)

I am using interface builder to create a masterview details application. However
when I run the app the cell gets misaligned.
Here is how it looks both on the simulator and on interace builder:
Any suggestion on how to fix this?
I have noticed that this happens also in the detail view controller that's why I choose the title of "misplaced view":
The problem in the first screen shot seems to be that you are not supplying a tall enough height for the cell. Thus some of the views on one cell are actually appearing on top of the cell below it. You need to fix your table view's rowHeight.
In the second screen shot, it looks like you are using auto layout but you are not doing auto layout (you have no constraints). You need to position these interface elements with constraints.
Check your constraints in interface builder first and make sure that your UITableViewDelegate is returning the correct heightForRowAtIndexPath:, then report back.
In Interface Builder, if you select one of these views that is not sized correct and then select the "size inspector" tab on the panel on the right (option+command+5), if you have no constraints defined, IB will warn you:
The selected views have no constraints. At build time, explicit left, top, width, and height constraints will be generated for the view.
If you don't see that sort of message, your screen snapshots suggest that you likely have constraints defined for the view which are tantamount to the same thing, left/top/width/height constraints.
The problem is that when you transition to a real device with different width, the layout of the view will not be correct.
If, however, you defined your own constraints (for example, notably using trailing constraint instead of width constraint, using bottom constraint rather than height constraint), you'll find the views will be better adjusted for the device's actual dimensions.
In your first example, iOS 8 will automatically adjust the row height of the cell if you had defined constraints. Something like:
V:|-[nameLabel]-[artistLabel]-[categoryLabel]-[priceLabel]-|
V:|-[imageView]-|
H:|-[imageView(100)]-[nameLabel]-|
H:[imageView]-[artistLabel]-|
H:[imageView]-[categoryLabel]-|
H:[imageView]-[priceLabel]-|
I'm showing it to you in VFL, but you can define it in IB, too. The key point is add constraints so that the vertical height is now unambiguous (i.e. the cell height will be adjusted to fit the labels) and the width is not hard coded, but rather the labels will expand/contract to fill it depending upon the device size.
Conceptually the exact same problem occurs in your second example, that you don't have leading and trailing constraints, but rather IB has defaulted to using leading and width constraints, which will not work as you go from device to device. For example, if you just want the text view, but have it adjust for the size of the device's screen, you might have constraints equivalent to the following VFL.
H:|-[textView]-|
V:|-[textView]-|

Autolayout, constraint and autosizing relationship in iOS

I've been following 6 or 7 tutorials already about table view cells, and they have been behaving seriously wrong (for example: as I click a row, the imageview resizes and covers the whole cell).
Since I'm new to iOS I have only read about things like constraints and auto-layout, and understand them theoretically. Given the fact that I have not set up anything related to auto layout or constraint, my storyboard prototype cell have only drag-n-dropped labels and imageviews and the Use autolayout checkbox is checked.
Up to this point, I have the theory that since use autolayout is checked, and no constraint is set up whatsoever, that is the cause of the strange behavior.
Also, in the Size inspector each view (imageview, label, other label) has different autosizing definition.
My question would be what is the relationship between autolayout, constraint, and autosizing

Content of scrollview changes size when scrolling

I'm using iOS 6 and Xcode 4.6 and with the Interface Builder I added to my controller a UIScrollView that uses all the available space. In this UIScrollView I added some views (a UIImageView, a UITextView and a UITableView (I disabled the scrolling for the UITextView and the UITableView)).
In the :
- (void) viewDidLayoutSubviews;
method I resized all my views by increasing their height (to fit with their respective content).
Then, I set the contentSize of my UIScrollView so that it fits with its content (my 3 views).
The resizing works and I can see them in my application when I run it.
Also, the scrolling is good (the contentSize is correct as I can scroll).
However, I have one big issue : as soon as I scroll, my 3 views are resized to their initial size (instead of keeping the size I assigned them via the frame property).
All my views are added with Interface Builder to my storyboard.
Do you know what I did wrong? Why my UIScrollView's content is reseting its size when I scroll?
Thank you for your help
You have auto layout enabled in your storyboard. When you scroll the scroll view, auto layout runs and resets your subview frames based on the constraints in the storyboard.
There are a few ways to fix this. One way is to turn off auto layout in your storyboard. Another way is to connect outlets to the constraints in your storyboard, and update the constraints (instead of setting the frames) to make auto layout put the views where you want them.

Resources