12

UICollectionView在单元格内有一个标签,它们会定期自动更改。当此更新触发时,我调用reloadDataUICollectionView 并设置单元格以更改背景颜色[UICollectionViewCell setHighlighted:].

问题是,如果用户按住某个单元格,则会发生更新,当用户释放该单元格时,该单元格将保持突出显示并且也无法再被选中。

我注意到dequeueReusableCellWithReuseIdentifier:forIndexPath:在 reloadData 之后对单元格调用 setHighlighted。

我也尝试过reloadSections:代替 reloadData,这解决了单元格“卡住”的问题,但在调用时会导致单元格淡出和进入。

将电话放在里面performBatchUpdates:似乎也不能解决问题。

4

5 回答 5

7

在单元格的类中尝试调用:

- (void)prepareForReuse {
    [super prepareForReuse];
    [self setHighlighted:NO];
    ... Any other custom stuff that should be cleaned up ...
}

问题是您可能正在做不同的背景着色,然后单元格在突出显示时通常会自行做。通常,单元格的超类会撤消 中的这些更改prepareForReuse,但它不知道您的更改。

于 2014-02-05T17:56:07.583 回答
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's 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);
}
于 2013-08-19T16:31:15.170 回答
2

我在不需要突出显示的集合视图中遇到了同样的问题,我注意到 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];
    }
}

它在我的情况下有所帮助,并且没有重新加载丢失。

于 2014-07-15T21:33:48.780 回答
0

我在我最近的一个项目中使用集合视图,以下代码对我来说很好。

    - (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;
}
于 2014-02-04T07:04:35.517 回答
0

可能不相关,但这让我很生气:在模式UIImage下呈现的实例默认突出显示。UIViewCollectionCell.alwaysTemplate

于 2018-06-21T15:15:44.537 回答