应用 CAAnimation 时,AQGridView 单元格被交换

Posted

技术标签:

【中文标题】应用 CAAnimation 时,AQGridView 单元格被交换【英文标题】:AQGridView cells get swapped around when CAAnimation is applied 【发布时间】:2011-12-12 15:49:43 【问题描述】:

有没有人成功地将动画应用到AQGridViewCells?我试图让每个单元格,但第一个单元格在点击后消失。

问题是当淡入淡出开始时,单元格内容通常会被交换。例如,如果网格视图的第一行包含标签为“1”、“2”、“3”的单元格,则标签可能会交换为“1”、“3”、“2”。

- (AQGridViewCell *)gridView:(AQGridView *)aGridView cellForItemAtIndex:(NSUInteger)index

    static NSString *CellIdentifier = @"ReusableGridViewCell";

    AQGridViewCell *cell = (AQGridViewCell *)[gridView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    
        [[NSBundle mainBundle] loadNibNamed:@"ReusableGridViewCell" owner:self options:nil];

        cell = [[[AQGridViewCell alloc] initWithFrame:gridViewCellContent.frame
                                      reuseIdentifier:CellIdentifier] autorelease];
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        [cell.contentView addSubview:label];
        [label release];

        cell.selectionStyle = AQGridViewCellSelectionStyleNone;
    

    UILabel *label = [[cell.contentView subviews] objectAtIndex:0];
    if (! tapped)
    
        label.text = [NSString stringWithFormat:@"%u", index];
       
    else if (index > 0)
    
        CATransition *cellAnimation = [CATransition animation];
        cellAnimation.duration = 3.0;
        cellAnimation.type = kCATransitionFade;
        cellAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        [label.layer addAnimation:cellAnimation forKey:kCATransition];              // labels get swapped
//      [cell.contentView.layer addAnimation:cellAnimation forKey:kCATransition];   // labels get swapped
//      [cell.layer addAnimation:cellAnimation forKey:kCATransition];               // labels get swapped, one cell immediately disappears
        NSLog(@"%u", [gridView isAnimatingUpdates]);                                // prints "0"

        label.hidden = YES;
    

    return cell;


- (void)gridView:(AQGridView *)aGridView didSelectItemAtIndex:(NSUInteger)index

    tapped = YES;
    [gridView reloadData];

我尝试在一堆AQGridViewAQGridViewCell 等方法中设置断点,以尝试找到导致交换的方法。没找到。

AQGridView的已知bug中,有这样的:

不要试图将多个动画堆叠在一起。 IE。 不要在 -isAnimatingUpdates 的网格视图上调用 -beginUpdates 方法返回 YES。坏事会发生,细胞最终会在 错误的地方,堆叠在一起。

在上面的代码中,-isAnimatingUpdates 返回NO。即便如此,也许我看到的是AQGridView 中的另一个相关错误——我将提交错误报告。但由于我的情况如此简单,我想知道是否有人以前遇到过它并想出了一个解决方法,也许是某种关闭AQGridView 内部动画的方法。

编辑

要查看问题是否与hidden 属性有关,我改为对单元格的不透明度进行动画处理(尝试了here 描述的两种方法)。即使不透明度仅下降到 0.5 而不是 0.0,单元格仍在交换。

【问题讨论】:

【参考方案1】:

这里有一个解决方法。如果有人找到更优雅的解决方案,我会将其标记为答案。

- (void)gridView:(AQGridView *)aGridView didSelectItemAtIndex:(NSUInteger)index

    // Create a copy of the 0th cell's content and display it on top of that cell.
    AQGridViewCell *selectedCell = [aGridView cellForItemAtIndex:0];
    UILabel *selectedLabel = [[selectedCell.contentView subviews] objectAtIndex:0];
    CGRect frame = [self.view convertRect:selectedLabel.frame fromView:selectedLabel.superview];
    UILabel *labelOnTop = [[UILabel alloc] initWithFrame:frame];
    labelOnTop.text = selectedLabel.text;
    [self.view addSubview:labelOnTop];
    [labelOnTop release];

    // Fade away the grid view as a whole (not individual cells). 
    CATransition *cellAnimation = [CATransition animation];
    cellAnimation.duration = 3.0;
    cellAnimation.type = kCATransitionFade;
    cellAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [aGridView.layer addAnimation:cellAnimation forKey:kCATransition];
    aGridView.hidden = YES;

【讨论】:

以上是关于应用 CAAnimation 时,AQGridView 单元格被交换的主要内容,如果未能解决你的问题,请参考以下文章

此 CAAnimation 会导致泄漏或保留周期吗?

如何在 iOS 应用程序中链接不同的 CAAnimation

当 CAAnimation 自动反转时,timingFunction 是不是也会反转?

停止 CAAnimation 以添加另一个 CAAnimation

CAAnimation - 更改动画最后一帧的属性?

如何在 animationDidStop 委托中识别 CAAnimation?