I have the problem with image loaded to the header cell, the problem was that requested image was not loaded (displayed as it turns out) and only the image loaded on view load was used.
I have narrowed the problem - I'm calling sizeToFit to resize label and then if the size is greater then minimum cell size I'm notifying delegate that I need new size of the cell. The delegate function calls reloadRowsAtIndexPaths:withRowAnimation: on the cell that was requesting resize. The tableView:heightForRowAtIndexPath: is called which is using new size.
I need this behaviour though as the cell needs to grow/shrink to accommodate the amount of text.
Has anyone faced similar issue, and most importantly has anyone got any workaround?
This is a sample project that shows this issue, if you go to the CSTitleCell and method resize to comment-out the delegate call you will see that it starts to work (but not resizing of the cell). Change of the content is done through swipe left/right.
Related
I'm trying to display an UIImageView in a UICollectionViewCell that is loaded after the cell is displayed initially.
To not display a white are I use a fallback image. This has a different size than the image to displayed later.
The sizeForItemAtIndexPath thus is called at a time when the bigger fallback picture is displayed and returns a size that is too big for the eventually loaded image.
I've implemented a delegate to call a method after the image has finished loading. The delegate method then calls reloadItemsAtIndexPaths on the UICollectionView with the indexPath of the cell that finished loading. This happens only if the calculated height of the cell now differs from the value calculated before. The image is also stored in cache after the initial load. Together this ensures that the reloadItemsAtIndexPaths method is only called once.
Although this works in general I'm not sure if it's the best practice. It also doesn't have the best performance and with small network speeds my layout doesn't look very good.
Has anyone ever encountered the same problem or was trying to dynamically resize single cells in the UICollectionView?
I had a similar problem with an image viewing app. I used invalidateLayout on the collectionViewLayout property of the collection view. It doesn't reload the cell, but calls sizeForItemAtIndexPath for the visible cells.
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
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
I am trying to have the content in a uicollectionviewcell grow bigger when it scroll moving in one direction. i initially set the size of the cell to the largest size i want, then the content inside the cell is half in terms of the size. the content is an uiimageview.
So I have a custom UICollectionViewFlowLayout in which I subclassed the layoutAttributesForElementsInRect to make the uiimageview in the cells grow bigger when it is moving in one direction. i also have shouldInvalidateLayoutForBoundsChange to return YES
Everything works perfectly when i scroll, the imageview will grow larger. However if i select a cell to push to a new viewcontroller, and then when i click the back button to come back to this uicolletionview, the enlarged uiimageview in severals cells are showing in the original size. They can only go back to the correct enlarged size if i scroll again, why is that? and how can i make it keep its enlarged size after getting pushed?
i tried invalidatelayout but it will just refresh the layoutattributes with correct enlarged size of the content, but the view is just not updated eventhough the size is already enlarged.
thanks
I had a similar issue when designing cv cells and would gess the issue is with when the subviews get calls to update their size, which might not happen when the view refreshes.
Instead of resizing content in the cell, you might want to dynamically size the cells themselves and have the content automatically adjust to that size. Calling [mycollection invalidateLayout] then should be all you need, maybe not even that.
The method is
collectionView:layout:sizeForItemAtIndexPath:
which you declare in your UICollectionViewFlowLayout.h
If you then run into trouble where subviews do not resize with cell size, related problems can arise from constraints/autolayout etc of the subviews.
Context:
Building an app that populates a table that takes in data from a asyc json dump.
The cells are of a custom class (I defined). The main label in the cell can be very long.
It is "placed" in storyboard within a prototype cell but customized via code (pretty standard stuff).
Labels are resized in cellForRowAtIndexPath and rows are resized via heightForRowAtIndexPath -- rows are resized by forcing a call to cellForRowAtIndex like Massimo's answer here
So per the question at hand - I've noticed some interesting (bad) things that happen.
First issue: When the table loads, the rows and labels are dynamically resized correctly! Great! However, when I scroll down and then scroll back up, the label heights will be incorrect -- (for example) the first row was correct at loading. Then when I scroll down and then scroll back up to see it again, it will be truncated. Specifically, the row size will be fine but the label height will change and become truncated to 2 lines only. Wondering if this is because I did both storyboard and coding to customize the cell. Anybody see this before?
Second issue: When I scroll down, while the rows are sized correctly (large), the labels are short (truncated.) Wondering if it's some reverse of the above "potential answer".
"potential answer" is that the rows are all calculated and stored "up front" so that scrolling down/then back up doesn't affect it. However, when cells go "out of view" and are dequeued then when they re-viewed (scroll down/then back up) it will rely on the storyboard.(inappropriately?)
All three of your issues are symptomatic of returning the wrong height in heightForRowAtIndexPath. In my data model classes I have a calculateHeight method that I call in heightForRowAtIndexPath. The model also caches the answer so it doesn't have to recalculate it after the first call. The cell class uses the model's calculated height to layout its subviews.
"ANSWERED" by deleting the prototype cell from the storyboard and making them fully in code, the issue went away. The fundamental workings are still not understood (ie. the interactions between storyboard vs. code when cells are put queued and then viewed again)