UITableView reusable cell or not - uitableview

I'm developing an app that represents a huge amount of data using UITableView with a custom UITableViewCell.
When the tableView is set to editing mode, it supports multiple selection for further usage of the selected set of data.
Using -tableView:didSelectRowAtIndexPath: and didDeselect I'm changing the rows UIImageViews image to a little tick and storing the selection into an array. When selecting a cell it gets light blue background (iOS standard).
When I'm now scrolling down and up again, the cells background is still light blue but the image is reset to default and the cells isSelected property is NO. Selecting it again invokes the -tableView:didSelectRowAtIndexPath: method.
After a while debugging it turned out that the reusable identifier was wrong. But as I corrected it, scrolling down repeated the same 12 cells over and over again. And the isSelected property is still reset to NO.
How can I maintain selected rows while scrolling the tableView?! And: Why is the cell blue highlighted (or marked as selected) but the isSelected property gets reset to No?
Thanks for help, with kind regards, Julian

Don't use the cell to hold persistent controller state. Instead keep an NSArray and add the NSIndexPath of each selected cell to your array (and remove them if/when the user deselects a cell).
Then in cellForRowAtIndexPath: just make sure you configure the cell correctly based upon whether or not its index-path is in your array of selected cells.

Related

Cell reuse bug in collectionView

Hello to all dear friends. I'm experiencing a problem with cell reuse. In practice I select multiple cells. In the "didSelected" method, I modify a property, called "isSelectedCell", to true and add a green border (to indicate the selection); While in the "didDeselect" method I carry it to false and remove the color of the border. But when I scroll down some cells, never selected, appear to be selected and the property is true. Because? How do I prevent this. It seems that when a cell is reused, the properties take on old ones and not their own.
If you are using a custom cell, override prepareForReuse and reset all properties to default values
override func prepareForReuse() {
super.prepareForReuse()
// reset custom properties to default values
}
Cells are for reuse means they are only fixed number of views which are used again. You have to update cells for every item to be displayed in that cell in collectionView cellForItemAtIndexPath method. You've to put it inside data source like array of objects to return correct value for every item. Hence it will remember to display which property on item.
Reusable cells are necesary to not bloat up the device memory and reuse same views.
it's due to the cell reuse of CollectionView.
as you can see in this article
when a cell disappear, it's reused to be the new one that going to appear.

Toggle Switch doesn't save is state when i scroll down the view and return up

In this view i have a table with cells composed by one label and one toggle.
If I try to change the state of this toggle it works, but if I scroll the view and than I returned to the toggle changed I found it in the previous state.
I have never worked whit this object so i don't know how to fix this issue.
You use 'UITableView', and all cells reuses for performance optimisation. You need check changing of UISwitch state and save it in your model. When your cell will reuse, you need to set saved state to UISwitch in tableView:cellForRowAtIndexPath: method.

Multiple cells got affected after calling cellForRowAtIndexPath

I have a UITableView, and I want to change text color of the selected row. But I see every other 15 row got affected along with the one I clicked. This is tested under the master-detail sample project.
if let indexPath = self.tableView.indexPathForSelectedRow(){
self.tableView.cellForRowAtIndexPath(indexPath)?.textLabel?.textColor = UIColor.redColor()
}
I checked cellForRowAtIndexPath value in debug session, it seems returning only one object, how come other cells got affected too?
Cells are reused - almost certainly you are not resetting your cells to a base state in prepareForReuse and configuring them correctly on each call to cellForRowAtIndexPath.
When you look at a table view that can display some number of cells at once, typically there will only exist one more cell than can be shown. When a cell is moved off the screen it is placed in a pool of cells for reuse. Just before a cell moves onto the screen it is configured by you, in cellForRowAtIndexPath. If you have configured something in the cell and you do not configure that explicitly every time you return a cell from cellForRowAtIndexPath then that configuration persists in the cell that is in the reuse pool. The function prepareForReuse is also called before each cell is reused - if you have subclassed UITableViewCell then you can implement this function to return the cell to a base configuration, so that settings like text color do not unexpectedly affect multiple cells.
This approach makes it possible to scroll through an entire table view smoothly with a minimum amount of memory used. It is an expensive operation to create and destroy cells every time one disappears and a new one is required.
The simplest fix is to always set the text color in cellForRowAtIndexPath - either to the base color or to the special color you want in some cells.

UICollectionView selection does not last

I have a UICollectionView I use like a tool selection container. You have many tools (the cells), when you select one, the former selected is deselected, and so on... You can only have one tool selected at a time.
The problem is that I can't manage to have the cells selected. When I tap the cell, the collectionView:didSelectItemAtIndexPath: is called. I then reload the selected cell to change it's appearance (I change the alpha of the image) by using the [collectionView reloadItemsAtIndexPaths:#[indexPath]].
Well that reloads the cell ok, except one damn thing: in the collectionView:cellForItemAtIndexPath: the cell never get the selected property set to YES! So I can never change the alphabecause I never know when I must draw a selected cell or not.
Worse: [collectionView indexPathsForSelectedItems] is always empty!!!
I don't even mention the collectionView:didDeselectItemAtIndexPath: that is never called...
Well, if someone can help me understand what is going on, thanks in advance...
When you call reloadItemsAtIndexPaths: the collection view discards those cells and creates new ones, therefor discarding the selected state of the cells.
I'd suggest a couple of different options:
1.) In collectionView:didSelectItemAtIndexPath: call cellForItemAtIndexPath: to get a reference to the selected cell and update it's appearance there.
2.) (My Favorite) Use a custom subclass of UICollectionViewCell if you're not already, and override the method setSelected:. There you'll be notified when the cell is selected and you can update the appearance from within the subclass.
With regards to selecting multiple cell at once, you should try the allowsMultipleSelection property [myCollectionView setAllowsMultipleSelection:YES] The docs for that are here: https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionView_class/Reference/Reference.html#//apple_ref/occ/instp/UICollectionView/allowsMultipleSelection
Otherwise, #daltonclaybrook's answer is sufficient.

Cancel animations in UITableView while scrolling

I am a bit confused and don't have much else to turn to. I have an iOS application that gets messages from a server and populates it into a cell in a UITableView. Every time a certain object gets updated from the server that update triggers a cell animation. In our case we have a table of scores in a game. If someone loses a point their cell would flash red and if they gain a point their cell would flash green. Simple concept that works well and our users like the feedback. What they don't like is how when they scroll they see the cells have random colors associated with it and stay there for about a second. I believe that it has something to do with the way that the cells are being recycled. I tried various checks regarding this issue, checking that the cell has the same value, setting the color manually to white, etc. and non of these methods work.
All in all I am trying to only show the animation when the cell has been in view and not when the users is scrolling through the UITableView. Anyone have any advice or ideas?
Thanks
What is happening
Since table views reuse their cells you are ending up reused cells that is being flashed even though they shouldn't.
How to solve it
You can restore the reused cell to its default state either in preprareForReuse: on the custom table view cell or in the tableView:willDisplayCell:forRowAtIndexPath: delegate method (as ACB mentioned).
Since you are animating with UIView animations, you only need to change the value of the animated property to cancel the animation and return to the default state.
If you would have user Core Animation for the flash
If the animation was done using Core Animation you would instead have called removeAllAnimations on the animating layer. (For a flashing animation you probably wouldn't change the property on the layer, instead you would tell the animation to autoreverse. This would mean that removing the animation would change the color back to its original value.)
One option is to remove the animation and reset the color in willDisplayCell delegate method to the default color. If that doesn't work you can set the dequeueReusableCellWithIdentifier as follows,
NSString *aCellIdentifier = [NSString stringWithFormat:#"%d",indexPath.row];
UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:aCellIdentifier];
But this will be a problem if you have a lot data to display as it will create memory issues. Note that in this case you will not be reusing the table cells.

Resources