CollectionViewCell keeps properties of old cell when reused - ios

I have a UICollectionView with several cells. At time properties of views inside the UICollectionViewCell change. I noticed that when one of the cells is reused the "new" cell "inherits" these changed properties from the old cell – even though they are set to their initial state in the initializer of the cell.
This is happening with AutoLayout Constraints posed on Views inside the Cell and the alpha property of views (things like the text of a UILabel and the image of a UIImageView are changing exactly like they should).
Is this common behavior or is there something wrong with my code? Is there anything I can do about it?

Related

UICollectionViewCell loaded from Xib (Nib) is being covered by storyboard cells as its size is not updating

I'm using a Xib file to hold a UICollectionViewCell item that I do not want to have in a Storyboard. I have the UICollectionView set to calculate its cell sizes automatically. But what I see when the collection view loads is that it's retaining the default 50x50 size for the cell that's being loaded from the Xib file. It's not being updated to the size it is showing up as.
The cell looks correct on screen and at the correct size. But when another cell loads that is contained in the storyboard it's loading on top of the other cell as its being placed 50 points down from the first cell.
The cell outlined in orange is the one being covered up by the one in green. I cannot show a larger portion of this due to work restrictions but I hope this clarifies what's happening.
I've tried to say that the cellNeedsLayout() and layoutIfNeeded() but neither of those make any difference. It's like the actual height that the cell is not being calculated early enough to have the collection view place cells around it correctly.
I've not been able to find a way to preload the Xib so that it already knows how large that needs to be. I am using a subclass of UICollectionView named CollectionCell.
Can anyone point me in the direction to look or suggest a fix for this other than moving what I've done into the Storyboard?

UITableViewCell repeating with scrollview - What workarounds are there?

So, my problem is pretty simple. I have a UITableView in a UIViewController. The tableview has dynamic cells (custom cells with images , text, etc.. from a subclass I created) and these cells belong to a subclass I created. Everything is going fine since the content is different on each cell. The problem is that when I scroll the scrollview of the cell which is horizontal ( I have a UIScrollView in the subview of the cell. I created this scrollview on the cell subclass), on let's say, indexPath.row == 0, and scroll the tableview vertically, after about 8 cells, the ninth cell has the scrollview scrolled as well. This is because of dequeuereusablecells, so the ninth cell is actually the first one, only displaying different content but since it is the first cell, it has the same background operation (the scrollview scrolled).
I tried to unscroll in the cellForRowAtIndexPath: but although this solves the problem it creates another : The first cell that was scrolled is not anymore. So, to solve this new problem I am planning on adding a workaround here that is a dictionary of [Int:Bool], that is, the indexPath corresponding to a Boolean value. If I scrolled the first cell, then 0:true. If I reach the ninth cell (which is equal to the first cell, but with IndexPath = 8 ), I unscroll the cell's horizontal scrollview. If I come back to the beginning of the tableview and reach the first cell, I scroll the cell's horizontal scrollview back. What do you guys think?
The other workaround I can think of is just not use dequeue reusable cells since I don't think I will have more than 30-50 rows on my tableview.
In terms of performance, which operation is better?
Firstly, I would suggest you to carefully analyse whether removing scrolling offset from the first cell is such a bad idea. If I am a user and I scroll down to the very bottom, making the first cell invisible, are you sure that I want it to return to the scrolled position after I scroll back to top? The answer might be Yes, but you should think about this carefully because it might lead you to the simplest solution.
However, in case you really need to do it, I would have a variable which stores the state of the scrolling for each row. If you have an array of objects from which you pull necessary properties (title, image etc) you can add this as an extra property to these objects. Otherwise, you can create an array which will be storing this info (I would prefer an array over dictionary for this task).
Fundamentally it's an issue caused by table view cell reusability. You can have workarounds, but I'd say that, things that aren't supposed to be reused should not be reused.
If your cells are all similar (with minor differences), you could use just one cell identifier; If you have very different types of cells, say, one type has a horizontal scroll view inside, one type just has some labels and images, you might want to consider to have two identifiers, so cells that have UIScrollView won't be reused for normal cells.
And at the same time, you can still do necessary cleanup works in prepareForReuse: to make sure cells that just get dequeued have a fresh start.

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

UITableViewCell selection behaviour changes when selectedBackgroundView is set

I have a UITableViewCell which is loaded from a xib, with a handful of labels and image views. I notice that when the .selectedBackgroundView property is set (in -awakeFromNib), interaction with the cell is only possible when touching on the labels or image views within the cell.
Trying to touch any blank space in the cell does nothing. Not setting .selectedBackgroundView returns the behaviour to normal.
Does anyone have a fix for this? (Mine currently is to place an empty UILabel over the entire contents of my cell)

Change frame of UIView in UICollectionViewCell in cellForItemAtIndexPath

My problem is very similar to this one, though the selected correct answer (which is just to use tags) didn't work for me (nor did any other answer): Changing label position in UICollectionViewCell.
I have a UICollectionView with a custom UICollectionViewCell. The cell has a UIView in it, which is referenced via IBOutlet property. I'm simply trying to change the frame within the cellForItemAtIndexPath method, and while the frame of the UIView is in fact changed, it is subsequently ignored, or not honored.
However, once the UICollectionView is scrolled a bit and it begins reusing cells, the reused cells do honor the previous change to the UIView's frame, and the UIView looks just like it should. So for some reason the first time cellForItemAtIndexPath is called for a particular cell, the frame change is ignored, but is subsequently honored once the cell is reused.
Actually, something more curious which I just noticed is that a reused cell has the size of the frame that had been previously changed, but keeps the original origin, which happens to be (0, 0), though I'm trying to update it to something like (0, 50).
Changing other properties of the UIView works fine, such as changing the background color. What might be happening to prevent the UIView's frame from initially changing?
UICollectionViewCell does not update frames for views that are defined in storyboard or xib files.
You have to create the view programmatically in your custom cells initWithFrame and/or awakeFromXib files.
Cheers!
hmmmm
I may be mistaken. I know this is true for UITableViewCell
Cannot update UI object's frame in UITableViewCell

Resources