UICollectionView - didDeselectItemAtIndexPath not called if cell is selected
The issue is, that the cell is selected, but the UICollectionView
does not know anything about it. An extra call for the UICollectionView
solves the problem:
[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
Full code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
cell.selected = YES;
[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
return cell;
}
I keep the question to help someone who may face the same problem.
UICollectionView DidDeselectItemAtIndexPath method not called in Swift
If the parent Class doesn't implement a delegate method, any Subclass won't be able to do it either.
Please make sure the Class you are Subclassing implements it.
didDeselectItemAtIndexPath is not working when reloadData is called
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
var cell : CollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath) as! CollectionViewCell
cell.backgroundColor = UIColor.magentaColor()
self.mediaModels[indexPath.row].isSelected = true
cell.selected = true
cell.imageTicked.hidden = false
}
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath){
var cell : CollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath) as! CollectionViewCell
cell.backgroundColor = UIColor.whiteColor()
self.mediaModels[indexPath.row].isSelected = false
cell.selected = false
cell.imageTicked.hidden = true
}
I get it to work without reloading the data. Just set the imageTicked hidden in the didSelectItemAtIndexPath and didDeselectItemAtIndexPath method. Thanks.
Swift 2 - Fatal Error when `didDeselectItemAtIndexPath` is called
Crash happened because the cell that you selected and scrolled out of the visible region of the screen had been reused for other cells in the collection view. Now, when you try to fetch that selected cell in didDeselectItemAtIndexPath
using cellForItemAtIndexPath
, it resulted in a crash.
To avoid crash, as mentioned by @Michael Dautermann, use optional binding to validate if the cell is nil and then set the alpha
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
cell.alpha = 1.0
}
}
In order to persist your selection state during scrolling, check the cell's selection state and set your alpha
value accordingly when you dequeue your cell in cellForItemAtIndexPath
method
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
if cell.selected {
cell.alpha = 0.4
}
else {
cell.alpha = 1.0
}
return cell
}
UICollectionView issue with Select/Deselect cell
As I understand, you want your collectionView
can only select 1 cell at a time and if selected cell is clicked again, it will be deselected. If I'm misunderstanding anything, please tell me.
First
- You shouldn't change
textColor
ofday
indidSelectItemAtIndexPath
anddidDeselectItemAtIndexPath
methods. Because when you scrollcollectionView
, cells will be reused and color ofday
will be wrong for some cells. To resolve it, using property selected of
UICollectionViewCell
.SmartCalendarDayCell.m
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
if (selected) {
self.day.textColor = [UIColor colorWithHexString:@"#D97E66" setAlpha:1];
} else {
self.day.textColor = [UIColor lightGrayColor];
}
}
Second
To deselect selected cell, you should check and do it on collectionView:shouldSelectItemAtIndexPath: method.
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if ([collectionView.indexPathsForSelectedItems containsObject:indexPath]) {
[collectionView deselectItemAtIndexPath:indexPath animated:NO];
return NO;
}
return YES;
}
For more detail, you can check my demo repo here.
UICollectionView's didSelectItemAtIndexPath only called when selecting cell with two fingers
The solution: The collection view was added on top of a view containing a single-tap gesture recogniser. This some how caused this behaviour. I removed the recogniser from the collection views parent view and it works.
Feel free to explain why this is expected behaviour. I would have argued that the top most view (CollectionView) handles the touches before they are passed to the view behind.
Related Topics
Waiting for Multiple Asynchronous Download Tasks
Centering Subview's X in Autolayout Throws "Not Prepared for the Constraint"
When How to Activate/Deactivate Layout Constraints
Correct Implementation of Parent/Child Nsmanagedobjectcontext
How to Change the Tint Color of the Clear Button on a Uitextfield
Screenshot for Avplayer and Video
Uitableviewcell Checkmark to Be Toggled on and Off When Tapped
How to Compare Two Nsdate Objects in Objective C
Distancefromlocation - Calculate Distance Between Two Points
Cannot Set Searchbar as Firstresponder
How to Add an Action to a Button Programmatically in Xcode
iOS Enterprise Ota Distribution Unable to Download Application
How to Play Mp3 Audio from Url in iOS Swift
Ios7 iPad Landscape Only App, Using Uiimagepickercontroller
How to Avoid Adding Multiple Nsnotification Observer