Are collection view cells reusable when they are inserted? - ios

I'm working on a view controller, where collection view cells are inserted when user scrolls.
I use reloadData() method only at the beginning. (viewDidLoad)
After first load, I use insertItems(at:) method whenever user scrolls.
There are a lot of cells to be added, so cells should be reusable.
But I'm wonder if cells are reused when I insert cell directly.
Are cells reused when they are inserted? (not reloadData)

Short answer: Yes, cells are reused.
Longer answer:
When you call dequeueReusableCell(withReuseIdentifier:for:) to get a cell for an item in the collection view it would return a reusable cell object located by its identifier.
Call this method from your data source object when asked to provide a
new cell for the collection view. This method dequeues an existing
cell if one is available or creates a new one based on the class or
nib file you previously registered.
Documentation

Related

iOS: UICollectionView content reset and dequeueReusableCell

Okay the situation goes as follows:
I have a collection view where in cellForRow I am using dequeueReusableCell to reuse the cells. On each cell I have a custom UIView object that is added as a subview.
Now, under a certain circumstance I must re-layout the collection view entirely. When this happens
Clear all item from data model
Call deleteItems for all visible cells' index paths
Call reloadData
At this point the collection view is empty and there are no cells displayed.
Now if I update my model again with data and reload the collection view - In cellForRow dequeueReusableCell returns reused cells/the added UIView as explained above is there!/- it does not initialize new cell objects even though the collection view was empty before the current update. I am not sure if this is the expected behaviour or I have some other problem in my code, however my question is - how can get to a point where I reset all the content on the collection view and dequeueReusableCell returns a newly initialized cell object.
I have learnt this the hard way! Save yourself some time Petar by knowing this that In any collection view/tableview, anytime there is any change of constraint or any UI element in its layout structure, you should ALWAYS, and ALWAYS make another prototype cell. It is the ONLY correct way, so don't think you ll be putting some more time in making another cell.
As I read your comment where you said you ll initiliaze another view based on that one condition where you want to reset everything. Just have another cell prototype with that another view and dequeue that now.
Hope it solves your problem

How to access UITableView Cell which is not yet in view?

I want to access/update UITableView cell (using reusable cells) which is not in the current view . I know the table view cells are reusable, that can be the reason I am unable to fetch them but is there any way of virtually making and updating. OR I have to drop the reusable cell technique. Suppose tableview have total 20 cells but only say 7 are visible in the current view of iPhone. How will i update other 13 cells which are out of view bounds
Accessing and modifying cells (even if you could) would be a bad pattern. UITableViewCells are designed to be created and modified solely in the tableView:cellForRow:atIndexPath datasource method, where framework automatically asks you what to do with cells that are about to be displayed.
The whole idea behind reusability is that the system takes care of the view for you, and all you need to do is take care of your datasource and instruct the system, using the model, how to render cells, in its allocated datasource method.
This paradigm would be defeated if we started accessing cells manually and modifying them.
You can't access those cells because they are not added to the UITableView but are kept in a queue until user scrolls to them, then they are added to the UITableView. Instead update your model, which will reflect changes on the cells.

why are my reusable UITableView header cells not being reused?

I have implemented the code necessary to take advantage of reusable header views as described in the accepted answer here
UITableViewHeaderFooterView in InterfaceBuilder
To summarize, I have a NIB who's class derives from UITableViewHeaderFooterView, I register the NIB in viewDidLoad "forHeaderFooterViewReuseIdentifier" and I dequeueReusableHeaderFooterViewWithIdentifier in the "viewForHeaderInSection" method. This all works, compiles, and runs.
The code closely parallels the typical use/re-use of UITableViewCells also being used in this screen. If I set a breakpoint on the dealloc methods for both (the table cells, and table header cells) I see the table cells get created, re-used, and rarely dealloc'ed.
The call to dequeueReusableHeaderFooterViewWithIdentifier returns a non-nil value and the result gets returned as the viewForHeaderInSection. However, the header cell dealloc method gets called (for each header cell) every time reloadData is called on the table. The table cells don't, so in other words the header cells aren't really being reused, if the cell behavior is the standard for defining "re-use". Or, at least it can be said that the header cells aren't re-used as much as the cells are.
Apple provides an example of header reuse in the "Table View Animations and Gestures" code example. If I add a dealloc method to their custom header class, it DOES get called when table reloadData is called. (I added a timer to their class that calls reloadData every 10 seconds)
Does anyone know if this is the expected behavior and I'm misunderstanding "reuse", or has Apple not really implemented the reuse behavior for header cells that is seen in table cells?
Thanks

Change another cell in dynamic prototype UITableView when a switch in one cell change

I used to use static UITableView but the table is too long and overflow the memory.
I switched a dynamic prototype UITableView with 1 type of cell, which has an UISwitch in it.
One of the cell, when turning on the switch, will turn off the switch of another cell. These cells have fixed index.
The IBAction method is in my UITableViewCell subclass and I don't want to add the UITableView as a property in my UITableViewCell.
How do I achieve the above effect?
I'm planing to use an id or similar to distinguish between the cells as each cell's switch has different effects, that doesn't solve the above requirement.
Thanks,
I would add a block property to your cell which you can use to notify your controller of changes in the switch. See my answer below to a question on this:
How can I get index path of cell on switch change event in section based table view
All your logic can now be implemented in the view controller.
You are best to create a data model in the view controller which the cells simply provide views and controls onto. When you flick one switch and the block fires, update the data model and simply reload the table. Any cells affected will show the new data model positions for their switches. Avoid using one cell to adjust another. Just update the model and reload the cells.

iOS: Adding row to tableview

I have a tableview that is based on a array of DB results, these results contains a date field. I have a custom cell that contains an image and labels. I'm trying to do:
At cellForRowAtIndexPath I verify if the date of current item (objectAtIndex:indexPath.row) has date field bigger than the last item (objectAtIndex:indexPath.row-1). If this is true: I want to add a cell filling the ImageView with a certain image, but I need to add a new row just for show this image.
How can I do this? I'm already doing this verification, but I need to add a new cell...
Do not use the cellForRowAtIndexPath to decide how many cells you want to have. At the point this method is called you should have already setup the data source to provide table view with all information needed.
Here is what you need to do. Refactor your code in a way so you:
Setup the data source first.
Force reload of the table view either by calling the reloadData method.
hey you can add the object in your data base(for example ns array) and refresh the table view with method
[tableView reloadData];
then the method cell for row at index path will be called again and it will refresh the table view's items.just make sure the method cellforrawantindexpath in your code knows to handle the new data type(make validations).
Your tableView data source should not contain any of that logic where the content of once cell depends on the content of another cell. Instead, you should have a data item for each requested indexPath and that data item should contain ALL logic necessary for the cell to be configured. If an action on that cell has an effect on how another cell should look, you apply a change to the corresponding data-item, and then call reloadRowsAtIndexPaths: for the indexPaths.
In short: configure cells ONLY in tableView:cellForRowAtIndexPath: or tableView:willDisplayCellAtIndexPath, and ONLY do configuring. Other logic should be placed in some data(-controller) object.
As suggested, you should add an item to your data-array. Then call -insertRowAtIndexPath: on the tableView. ReloadData is like a big ugly hammer that you only use when ALL of the data for that tableView changes.

Resources