iOS 7 UITableView Not Getting Right Cell Height Until Refresh - ios

For some odd reason, my table view sets the height of each custom UITableViewCell to a default value of 44.0f despite me explicitly returning a value of 113.0f in the datasource method. I made sure that I set my view controller as the datasource and delegate so that's not the issue but I'm completely stumped. I saw another SO post where someone was asking a similar question, the tableview wasn't getting the proper cell height until after a forced refresh. I'm even calling [tableView reloadData] in every possible uiviewcontroller method and that's not changing anything. Anyone have any ideas/possible fixes?
EDIT:
So here's the weird part. The cell's are visually getting set to the right height but their frame's are returning a value of 44.0f. What's more, all the subviews are sized down to 44.0f even though when I tap a cell, all 113 pixels gets highlighted.

If you use prototype cells, or if you load their interface from a .xib file, check if they have the right height in the Interface Builder

Related

UITableview with Autolayout and NSFetchedResults controller cell layout bug on insert

I seem to be having a very strange problem with my UITableview cells and autolayout. So my tableview is set up as follows:
I have a UITableView within a UIViewController that I created via Interface builder using Autolayout
My tableview is using UITableViewAutomaticDimension so that the cells can resize based on the text within them.
Each cell has 2 subviews within it. A front view and a back view. The back view contains the buttons for my slide-able cells
I am using NSFetchedResults controller to update the tableview
The problem occurs when I tap on a cell and am taken to the next view. Then I create a core data item within that view and save so that it is inserted into my tableview (now behind the current view controller).
What happens is that the newly inserted cell seems to lose all autolayout constraints and all view elements are on top of each other in the top left of the cell. It also looks like they are not even contained within the front view for the cell (or the front view has a width and height of 0).
Example:
It gets even stranger. If I refresh the tableview by pulling down and the cells are reloaded it corrects itself. However, if I refresh the tableview again then the problem appears again but on a different cell. This bug does not happen consistantly which is rather frustrating.
Any help would be appreciated as I only have a few remaining hairs on my head to pull out at this stage.
Thanks in advance!
So I found out what the issue was. The issue was that I was using size classes in Interface builder but I was only using the iPhone Portrait size class and did all my work in there instead of the "any" size class. Disabling size classes and setting the project to iPhone only fixed all these problems.
Weird I know

Dynamic cell height issue with UITableViewCell autolayout jerk while scrolling

I am trying to do something like loading up different type of cells with custom height in a uitableview. The tableview cells are subclassed and consists of labels with the respective constraints. Each cell is having a dynamic height.
Now even before my table reloads the data, I am calculating the height that is required for the resizing of the cells and caching it in my model class so that I dont have to calculate the height when the data is rendered on the device.
To calculate height i did use the tutorial from Ray Wenderlich and I am having the right set of heights applies to the objects.
Now the problem comes. Whenever I am dequeueing the cells there is a
kind of a small jerk that gives me an indication that my cell is
dequeued while scrolling.
How can i make these movement smooth so that there is no jerk while scrolling the view ?
The height is getting assigned in and does get the value as per the current type of data getting loaded.
estimatedRowForIndexPath
Also I am calling layoutIfNeeded from my cellForAtindexPath
Suggestions are most welcome.
It's very hard to say without seeing your code in cellForRowAtIndexPath, and without seeing your cells and their respective code. Here are some general questions I would investigate:
What is the content of the cells and how complex is the view hierarchy in the cell?
Even though you are supplying the correct estimated height, an autolayout pass still needs to happen, and a complex view hierarchy will take time to resolve
Does the cell contain images?
Images that need to be decompressed from a file (UIImage imageNamed:) can be intensive and cause scrolling issues, check images are not bigger than they need to be. If needed, bump this work onto a background thread.
Are you calling a complex method to configure the cell for display in cellForRowAtIndexPath?
Look at the work actually being done in cellForRowAtIndexPath, is there a complex method being triggered in you cell subclass or view model?
Are you adding and removing views to the cell view hierarchy in cellForRowAtIndexPath?
If views are being added, removed, created, inflated from a xib, constrained etc during the cell config, this could slow things down. Try to do only what is strictly needed. Check if there is any code being run internally in the cell subclass during cellForRowAtIndexPath that could be moved to cells initWith... or awakeFromNib methods (ie code that could just run once when the cell is created, rather than every time the cell is displayed)
Also run the Instruments time profiler, see if that offers any more clues

UICollectionView within UITableView. How to tell tableview cell to change height when collection view gets taller?

I have a UITableView and one of my table cells is a UICollectionViewController subclass that contains a UICollectionView of displayed email addresses. When a user adds an email the UICollectionView and it’s cell in the table view should get taller.
I’m currently attempting to do this setting my collectionView height constraint to collectionView.contentSize.height in the LayoutSubviews method of my collection controller/cell class. My issue is that the cell in the UITableView is not changing size when this happens.
I am assuming that this is because there is nothing telling the table view that the height of the email entry cell has changed. I am currently using dynamic cell sizing - or trying to anyway. Even, if I call tableView.reloadData() this still does not work. I’m wondering if someone could give me a high-level idea of how they would set this up.
UPDATE:
I had a broken constraint issue that was part of my problem, but this is still not solved. While have proven that I can update the height constraint and that will update the size of the collection view, it's out of sync. It's always one update behind. Here's an image showing the 'UICollectionView' in green and you can see in the logs that I'm updating the constraint (yes, multiple times) each time after adding a new item to the collection, but it is not updating the bounds of the view instance. In this example, if I were to add a new item to the collection, the next time I inspect bounds.height it would be at 149.5. What am I missing!?
i had answered this question in another tableview inside tableview cell that will work for collection view too ,i explained it in this thread
ask me if you faced any problem
It seems you want to set the height of your table view cell dynamically. This detailed tutorial walks you through making a custom cell class that will have dynamic height. Unfortunately, this tutorial only walks you through how to do this with auto layout constraints and a storyboard. In the tutorial you'll notice that the height of the cell depends on the constraints put on a title label within the cell. Try doing the same thing, but applying the constraints on the content in your cell (the collection view cell).
http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout

How to fix UITableViewCells cutting off at a fixed height in iOS7?

I have a UITableView in my app where each UITableViewCell has a custom view added to its contentView. Now, each such custom view can come at any height and I verified that tableView:heightForRowAtIndexPath: returns the correct value. The thing is it used to work just fine prior to iOS7. In iOS7 it cuts off every cell's content at the exact same spot, about 40-50 points from the top. I can see using the table view's separator that each cell has the correct height, so it isn't a matter of the cell going beyond its bounds and being clipped. It is clipped while being contained fully inside the cell's bounds.
Anyone has any idea what is the cause of this issue and how to solve it?

UITableViewCell frame height not matching tableView:heightForRowAtIndexPath:

I'm constructing a UITableView with variable height custom table cells, their height determined by the size of a contained multi-line UILabel. I've got the tableView:heightForRowAtIndexPath: delegate method wired up and calculating the final height correctly using sizeWithFont:constrainedToSize:.
I've run across strange issue: by the time the data source method tableView:cellForRowAtIndexPath: is called, the correct per-row height has already been determined as described above, but the frame of the cell does not match that height. Instead, the frame.size.height property of the cell is the default cell height of the table view (86 px, as I've set it in Interface Builder, the correct height when the contained UILabel has just one line of text), instead of being the height that tableView:heightForRowAtIndexPath: determined correct for that index path.
I'm producing the cells in cellForRowAtIndexPath: using dequeuing, that is,
// Using storyboards, this never returns nil, no need to check for it
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"SomeIdentifier"];
NSLog(#"%f", cell.frame.size.height); // 86, not correct if the cell contains a multi-line UILabel
It seems, then, that whatever iOS is doing behind the scenes, the dequeuing is not setting the frame property of the cell to match the calculated height. This in itself is not that surprising, dequeuing concerns itself with cell instances, not their geometry. The cells are rendered correctly, though, so the height property is being set somewhere, but it happens after cellForRowAtIndexPath:.
So: when I initially populate the table view, cell.frame.size.height is 86 for all the cells as they appear for the first time when I scroll the list downwards. Since the correct geometry is set sometime after the first cellForRowAtIndexPath: for each row before it's displayed, when I scroll back up, the height property is correct for each cell that comes back into view after being reused.
After this I can scroll the table view back and forth at will, and the height property remains correct for each cell from that point on.
What's the correct way of getting the correct cell height the first time around, before any dequeue-based reuse happens? I need this to do a bit of re-positioning of the subviews of the table cell. Do I need to manually call heightForRowAtIndexPath: in cellForRowAtIndexPath: and then manually set the frame of the freshly created CustomCell instance to match that height? This seems redundant, and I'd need to create a mechanism to detect when the cell is created for the first time with the wrong frame height vs. when it is dequeued with the correct frame height later to avoid this redundancy.
So, if someone can shed some light into what the logic is behind this, I'd appreciate it.
As suggested by Flexo, answering this myself is apparently better than adding an edit to the question. So, here's the previous edit as an answer:
Nevermind, I should read the docs better. I can get the correct frame in the tableView:willDisplayCell:forRowAtIndexPath: method of UITableViewDelegate, so that is the correct place to do subview customization that relies on the correct frame being set, not cellForRowAtIndexPath:.
Interesting that the docs say this, though:
After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out.
...since the correct frame is already there when this delegate method is called. But anyway, problem solved.
Don't forget that the cell is a UIView, so overriding layoutSubviews is also a valid way to get the correct frame and adjust size/position of subviews. Just don't forget to call [super layoutSubviews].
Easiest way I found was just to call cell.layoutIfNeeded() before you do any setup on the cell. This makes sure all the layout constraints are calculated and the frames are set.

Resources