UITableViewCell子类,用代码绘制,动画中的删除按钮

Amy*_*all 6 cocoa-touch core-animation uitableview ios

我正在开发一个自定义的UITableViewCell子类,其中所有内容都是用代码绘制而不是使用UILabels等.(这是部分学习练习,部分原因是因为代码绘制速度要快得多.我知道对于几个标签它不会产生巨大的差异,但最终我想把它推广到更复杂的细胞.)

目前我正在努力使用删除按钮动画:如何在删除按钮滑入时为单元缩小设置动画.

图片

首先,我正在绘制单元格contentView的自定义子视图.一切都是在那个子视图中绘制的.

我通过在单元格本身上捕获layoutSubviews来设置子视图的大小,并执行:

- (void)layoutSubviews
{
    [super layoutSubviews];
    CGRect b = [self.contentView bounds];
    [subcontentView setFrame:b];    
}
Run Code Online (Sandbox Code Playgroud)

我这样做而不仅仅是设置自动调整掩码,因为它在测试中似乎更可靠,但我可以在测试中使用自动调整掩码方法(如果需要).

现在,当有人点击减号时发生的默认事情是视图被压扁.

在此输入图像描述

在设置我的手机时,我可以避免这种情况

subcontentView.contentMode = UIViewContentModeRedraw;
Run Code Online (Sandbox Code Playgroud)

这给了我正确的最终结果(我的自定义视图重新绘制了新的大小,并且布局正确,就像我发布的第一张图片一样),但过渡的动画令人不快:它看起来像细胞拉伸并收缩回到尺寸.

我知道为什么动画是这样的:Core Animation不会要求你的视图重绘每一帧,它会重新绘制动画的结束位置,然后进行插值以找到中间位.

另一种解决方案是做

subcontentView.contentMode = UIViewContentModeLeft;
Run Code Online (Sandbox Code Playgroud)

这只是在我的单元格上绘制删除按钮,所以它覆盖了它的一部分.

在此输入图像描述

如果我也实施

- (void) didTransitionToState:(UITableViewCellStateMask)state
{
    [self setNeedsDisplay];
}
Run Code Online (Sandbox Code Playgroud)

然后,一旦删除按钮在单元格中"滑动"滑动到正确的大小.这样就没有漂亮的滑动动画了,但至少我在最后得到了正确的结果.

我想我可以在出现删除按钮的同时运行我自己的动画,暂时创建另一个视图,其中包含旧视图中我的视图图像的副本,将我的视图设置为新大小,并在它们之间淡入淡出 - 这样就会是一个很好的交叉淡入淡出,而不是一个急剧的跳跃.有人用这种技术吗?

现在,你可能会问为什么我不能使用该contentStretch属性并给它一个区域来调整大小.问题是我正在做一些合理的通用,所以它并不总是可行的.在这个特定的例子中,它可以工作,但更复杂的单元可能不会.

所以,我的问题(在所有这些背景之后)是:在这种情况下你做了什么?有没有人有自定义绘制单元格的动画删除按钮?如果没有,最好的妥协是什么?

Rui*_*res 1

所以我先贴一下代码,然后再解释:

-(void)startCancelAnimation{
    [cancelButton setAlpha:0.0f];
    [cancelButton setFrame:CGRectMake(320., cancelButton.frame.origin.y, cancelButton.frame.size.width, cancelButton.frame.size.height)];
    cancelButton.hidden=NO;

    [UIView animateWithDuration:0.4
                     animations:^(void){
                    [progressView setFrame:CGRectMake(progressView.frame.origin.x, progressView.frame.origin.y, 159.0, progressView.frame.size.height)];
                    [text setFrame:CGRectMake(text.frame.origin.x, text.frame.origin.y, 159.0, text.frame.size.height)];
                    [cancelButton setFrame:CGRectMake(244., cancelButton.frame.origin.y, cancelButton.frame.size.width, cancelButton.frame.size.height)];
                         [cancelButton setAlpha:1.0f];    
                     }  ];
}

-(void)stopCancelAnimation{
    [UIView animateWithDuration:0.4
                     animations:^(void){
                        [cancelButton setFrame:CGRectMake(320., cancelButton.frame.origin.y, cancelButton.frame.size.width, cancelButton.frame.size.height)];
                         [cancelButton setAlpha:0.0f];
                     }completion:^(BOOL completion){ 
                         cancelButton.hidden=YES;
                         [cancelButton setAlpha:1.0f];
                         [progressView setFrame:CGRectMake(progressView.frame.origin.x, progressView.frame.origin.y, DEFAULT_WIDTH_PROGRESS, progressView.frame.size.height)];
                         [text setFrame:CGRectMake(text.frame.origin.x, text.frame.origin.y, DEFAULT_WIDTH_TEXT, text.frame.size.height)];
                        }
     ];

}

-(void)decideAnimation{
    if([cancelButton isHidden]){
        [self startCancelAnimation];
    }
    else{
        [self stopCancelAnimation];
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我有一个看起来像这样的按钮: 在此输入图像描述

我有一个IBOutlet。我正在做的是调整 aUIProgressView和 a 的大小UITextField(你可以调整任何你想要的大小)。至于代码非常简单,但如果您需要任何帮助来理解发生了什么,请询问。另外,不要忘记将滑动手势添加到UITableView...,如下所示:

    UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
    gesture.numberOfTouchesRequired=1;
    gesture.direction = UISwipeGestureRecognizerDirectionRight;
    [table addGestureRecognizer:gesture];
    [gesture release];
Run Code Online (Sandbox Code Playgroud)

最后是完成这一切的方法:

-(void)didSwipe:(UIGestureRecognizer *)gestureRecognizer {

        if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
            //Get the cell of the swipe...
            CGPoint swipeLocation = [gestureRecognizer locationInView:self.table];
            NSIndexPath *swipedIndexPath = [self.table indexPathForRowAtPoint:swipeLocation];
            UITableViewCell* swipedCell = [self.table cellForRowAtIndexPath:swipedIndexPath];
            //Make sure its a cell with content and not an empty one.
            if([swipedCell isKindOfClass:[AMUploadsTableViewCell class]]){
                 // It will start the animation here
                [(AMUploadsTableViewCell*)swipedCell decideAnimation];
                // Do what you want :)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,整个动画都是手动创建的,因此您可以准确控制您想要的内容。:)