I have a UICollectionView that renders some autosizing cells. When I load the data into the collection view initially, the data is perfectly sized the way it should be.
I have a weird issue where, when I trigger reloadData with a new data set, the auto sizing goes wrong and I end up with incorrectly sized cells.
Images attached.
I have tried invalidating the collectionViewLayout before I call reloadData.
Oddly enough, if I remove data, and trigger a reloadData the cells resize to their correct layout. So I am wondering if this is a view recycling issue?
Thanks in advance.
Below is the layout after the screen was initially loaded for the first time.
Below is the layout after the + opens a modal to add a new post, closes, and refreshes the data - see incorrect sizing of cell "Thanks for all your hard work".
Below is the screen after the screen was reloaded from scratch again.
My answer might be a bit late, but getting the similar behaviour I did manage to solve it.
In my case, the problem was with multiline labels — so changing them to single-line solved the case.
As I didn't need to have multilines — I had no further research on them.
I hope, this answer could be a good starting point to find a fix.
Related
I'm trying to optimize the UITableViewController for slower devices, and after eliminating many of the reasons why a tableview might be slow, I'm still trying to figure out the last one...
This screenshot is from instruments, showing the most expensive calls, during a time where no call is made to get heightForRowAtIndexPath or cellForRowAtIndexPath (scrolling ~10px up and down repeatedly without causing any cell to go out of the table, or get rendered).
Is this normal behavior? Why would the view need relayout if the content of the page is not changing?
Every time you scroll, you change the contentOffset. contentOffset updates bounds, specifically its origin. Every bounds change marks receiver for layout need in next update cycle. In this case to update frame of floating subviews like scroll indicator, table headers and footers, ... This is totally normal behaviour and there is nothing you can do about it. Don't worry, you are redisplaying, not redrawing.
We'd have to see some code to identify exactly why that method is being called but it could be from one of these reasons at least:
You have constraints that are being changed when scrolling even if you don't see it, they might be affected, maybe inside the UITableViewCell?
It does't have anything to do with the table view, the view just has something else to layout, maybe you made a constraint modification...
Your calling a method thats calls it explicitly.
Also remember this will only layout the view 'if needed'.
Learning efficient ways of calculating the height of dynamic tableview cells with autolayout. Faced the problem when scrolling table view, it begins to stutter a little bit, which is very annoying. Sometimes it stutters a lot when scrolling up, but that is probably related to my demo core data code.
This video demonstrates the problem. The sample project is on github repository (see SZNewsFeedViewController).
The layout of the cell is very simple:
My first guess was looking at blended layers in the simulator, but it's fine:
Stuttering does not go away if I comment out images setting, so, that is probably not the real reason. I set the images asynchronously with FastImageCache. I think I could watch for active scrolling and skip images setting until it stops completely, but I'm not sure if this could really help.
Replacing tableView:heightForRowAtIndexPath: code with return 250 does not solve the issue completely too.
Right now I change the height constraint constant for posts with images, will try a separate cells for plain text posts and images posts.
Can you point me out, what may cause such a stuttering and what can i try more to solve it? What's wrong with my layout or height calculating code?
Is there any appropriate way to pre-calculate heights (with the same values as systemLayoutSizeFittingSize returns) in the background thread and save it to core data model, to be able to reuse those values fast?
EDIT: the profiler say that height calculating takes most of the time:
UPD:
Ok, seems like a separate cells + height caching is a better solution - tableview jiggles less for a little bit. Also, tableView:estimatedHeightForRowAtIndexPath: seems to be more harmful then helpful. Removing this method removes jiggling a little bit more too. I figured out that after the approaches above, [collectionview reloadData] call affects most of all - removing this call leads to almost no jiggling. I will try static imageviews + watching the active scrolling to determine if this wouldn't lead to jiggling.
It looks like you're still implementing heightForRow:atIndexPath: and not utilizing UITableViewAutomaticDimension.
So, I have an issue that seems to have cropped up after having updated the Xcode program on my Mac. I have a tableView that houses an image and subsequent comments underneath, which are initially offscreen until you scroll down and then they load up. The issue I seem to be having is that the cells wont adjust their heights respectively unless I first scroll down to get them loaded, scroll up and then down again. Only then will the UITableViewAutoDimension seem to take effect.
Any suggestions? My auto-laying is exactly how it should be to accommodate dynamic heights of UILabels.
Let me know if more information is needed.
Cheers in advance.
So after about 10 hours of pulling my hair out and literally debugging to sh*t, I found that I had 'use size classes' selected along with 'use auto constraints' which was completely destroying any chance of the table cells from resizing first time. I switched 'use size classes' off in the interface builder document and it seems to have resolved the issue. All I can say is thank f**k! 👍
I'm using a custom UITableViewCell with an UIControl and a few UILabels in my UITableView and everything works fine only if the UITableView takes up the whole screen. I'm using a xib file for this.
The problem is that I need to resize the UITableView to take only the bottom half of the screen, and like this only the first row accepts touches. Also if I try to scroll by pushing up from lower cells it won't do it, but will only scroll if I hold the first row.
It happens on both iPad and iPhone, but it's particularly bad on the iPhone. It seems that only on the bottom half of the screen the scrolling doesn't work.
I've already checked all views, and there is none above the UITableView, I've checked all sizes, I've googled and searched on Stackoverflow, but I couldn't find anything similar to my problem.
What else do I need to be checking? Any thoughts on this?
The problem was that I had a custom Marquee UILabel, allocated and initialized via code and not via xib file, at the bottom of the screen and I was using the iPad frame instead of the iPhone one, so it was huge, being placed above the UITableView, consequently blocking it and preventing touch events.
As I was so focused on the xib file I totally forgot that I had setup this custom Marquee UILabel via code.
I thank Ethan Holshouser and Helium3 for all helpful comments above and the Reveal App suggested by Helium3 helped me greatly visualizing the views hierarchy to solve the problem.
I'm using ECSlidingViewController. When the app starts, it opens a scroll view which is resized dynamically, since it contains both labels and a table view. Both the table and the scroll view containing it are resized.
Everything works as intended when the view is first loaded. However, if I open and close the menu view, or if I use it to go to any view which resizes itself, the resizing does not work. Instead, it displays the scroll view as if it has the height assigned to it in the storyboard.
I'm completely lost as to why this happens, and would greatly appreciate help. I can post code as well, of course, but I don't know what code might help, since I guess that the error is on ECSlidingViewController's part.
Are you using auto layout? If so, whenever something else happens that triggers the application of the constraints, all the frames will be reset to the values dictated by those constraints. Try turning off auto layout and see if that fixes it. Refer to your auto layout settings.
Alternatively, if you want to keep auto layout, I'd generally suggest changing the frames by programmatically changing the constant values of the constraints. But, I'm not familiar with ECSlidingViewController, so I don't know if that's a reasonable option in this particular case.