Ячейки UICollectionView остаются выделенными после перезагрузки
У меня есть UICollectionView
с ярлыками внутри ячеек, которые автоматически меняются автоматически. Когда это обновление запускается, я вызываю reloadData
в UICollectionView, и я установил ячейки для изменения цвета фона на [UICollectionViewCell setHighlighted:].
Проблема заключается в том, что пользователь удерживает ячейку, тогда обновление происходит, когда пользователь освобождает ячейку, выделенную и также не может быть выбрана больше.
Я заметил, что dequeueReusableCellWithReuseIdentifier:forIndexPath:
вызывает setHighlighted на ячейках после reloadData.
Я также попробовал reloadSections:
вместо reloadData, это исправляет проблему того, что ячейки "застревают", но вызывает угасание и появление в ячейках когда-либо их вызываемых.
Размещение вызовов внутри performBatchUpdates:
также не устраняет проблему.
Ответы
Ответ 1
Внутри класса ячейки попробуйте позвонить:
- (void)prepareForReuse {
[super prepareForReuse];
[self setHighlighted:NO];
... Any other custom stuff that should be cleaned up ...
}
Проблема заключается в том, что вы, вероятно, делаете фоновое окрашивание по-разному, тогда ячейка обычно делает это самостоятельно, когда подсвечивается. Обычно суперкласс класса отменяет эти изменения в prepareForReuse
, но он не знает о ваших изменениях.
Ответ 2
В качестве обходного пути я использовал следующее:
// Both highlightedData and lastHighlightedData are only needed if you want to prevent user from selecting a cell which data changed during the reload. If not needed, a boolean may be used instead
@property (nonatomic) id highlightedData;
@property (nonatomic) id lastHighlightedData;
@property (nonatomic) BOOL pendingCollectionViewReload;
// Wrap the reloadData call. Enqueue it if there a highlighted cell:
- (void)reloadCollectionView
{
if (self.highlightedData) {
self.pendingCollectionViewReload = YES;
return;
}
[self.collectionView reloadData];
self.pendingCollectionViewReload = NO;
}
// When a cell is highlighted, save its index, or better the related data:
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
// Save data at indexPath to self.highlightedData
}
// Then reload the data when the cell is unhighlighted:
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
self.lastHighlightedData = self.highlightedData;
self.highlightedData = nil;
if (self.pendingCollectionViewReload) {
[self reloadCollectionView];
}
}
// The following can be used from shouldPerformSegueWithIdentifier or didSelectItemAtIndexPath to prevent actions if the data associated with the indexPath changed:
- (BOOL)selectedDataEquals:(id)data
{
// I used lastHighlightedData in addition to highlightedData because this function may be used after the didUnhighlightItemAtIndexPath was called:
return (self.highlightedData && self.highlightedData == data) || (!self.highlightedData && self.lastHighlightedData == data);
}
Ответ 3
Я столкнулся с той же проблемой в представлении коллекции, который не нуждался в подсветке, и я заметил, что методы didHighlight/didUnhighlight ведут себя правильно, поэтому я закончил блокировку перезагрузок во время касания, используя что-то вроде этого:
BOOL blockColviewUpdate,colviewUpdateQueued;
а затем
-(void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
blockColviewUpdate=YES;
}
-(void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
blockColviewUpdate=NO;
if(colviewUpdateQueued==YES) [self CollectionViewRefresh];
}
при использовании собственной функции вместо прямого вызова reloadData:
-(void)CollectionViewRefresh
{
if(blockColviewUpdate==YES) colviewUpdateQueued=YES;
else
{
colviewUpdateQueued=NO;
[self.colview reloadData];
}
}
Это помогло в моем случае, и никакие перезагрузки не были потеряны.
Ответ 4
Я использую коллекции в одном из моих последних проектов, и следующий код работает отлично для меня.
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath: (NSIndexPath *)indexPath
{
return YES;
}
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
{
return YES;
}
В подклассе collectionviewcell
@interface SalesLegendCell: UICollectionViewCell
ниже приведен код
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"SalesLegendCell" owner:self options:nil];
if ([arrayOfViews count] < 1) {
return nil;
}
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[SalesLegendCell class]]) {
return nil;
}
self = [arrayOfViews objectAtIndex:0];
UIView* backgroundView = [[UIView alloc] initWithFrame:self.bounds];
backgroundView.backgroundColor = [UIColor colorWithWhite:0.85 alpha:1];
UIView* selectedBGView = [[UIView alloc] initWithFrame:self.bounds];
selectedBGView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1];
self.selectedBackgroundView = backgroundView;
self.backgroundView = selectedBGView;
}
return self;
}