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

时间:2011-04-21 10:27:28

标签: cocoa-touch ios uitableview core-animation

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

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

image

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

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

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

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

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

enter image description here

我可以在设置我的手机时调用

来避免这种情况
subcontentView.contentMode = UIViewContentModeRedraw;

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

我知道动画为何如此工作:Core Animation不要求你的视图为每一帧重绘,它会重新绘制动画的结束位置,然后进行插值以找到中间位。

另一个解决方案是

subcontentView.contentMode = UIViewContentModeLeft;

只是在我的单元格上绘制删除按钮,因此它覆盖了部分内容。

enter image description here

如果我也实施

- (void) didTransitionToState:(UITableViewCellStateMask)state
{
    [self setNeedsDisplay];
}

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

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

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

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

2 个答案:

答案 0 :(得分:2)

这最终对我有用。在UITableViewCell的子类中

subDrawContentView.contentMode = UIViewContentModeLeft;

覆盖layoutsubviews方法

- (void)layoutSubviews {

    CGRect b = [subDrawContentView bounds];
    b.size.width = (!self.showingDeleteConfirmation) ? 320 : 300;
    [subDrawContentView setFrame:b];
    [subDrawContentView setNeedsDisplay];

    [super layoutSubviews];
}

答案 1 :(得分: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];
    }
}

所以我有一个看起来像这样的按钮: enter image description here

我有一个IBOutlet。而我正在做的是调整UIProgressViewUITextField的大小(您可以调整所需的大小)。至于代码非常简单,但如果您需要任何帮助来了解正在发生的事情,请询问。另外,不要忘记将Swip Gesture添加到UITableView ...像这样:

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

最后是完成所有工作的方法:

-(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 :)
            }
        }
    }

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