UITableViewCell 子类,在代码中绘制,动画中的删除按钮
Posted
技术标签:
【中文标题】UITableViewCell 子类,在代码中绘制,动画中的删除按钮【英文标题】:UITableViewCell subclass, drawn in code, animate Delete button in 【发布时间】:2011-04-21 10:27:28 【问题描述】:我正在开发一个自定义 UITableViewCell 子类,其中所有内容都是在代码中绘制的,而不是使用 UILabel 等。(这部分是学习练习,部分是因为在代码中绘制要快得多。我知道对于几个标签它不会有很大的不同,但最终我想将其推广到更复杂的单元格。)
目前我正在为删除按钮动画而苦苦挣扎:如何在删除按钮滑入时使单元格收缩。
首先,我正在绘制单元格内容视图的自定义子视图。一切都在那个子视图中绘制。
我通过在单元格本身上捕获 layoutSubviews 来设置子视图的大小,并执行以下操作:
- (void)layoutSubviews
[super layoutSubviews];
CGRect b = [self.contentView bounds];
[subcontentView setFrame:b];
我这样做而不是仅仅设置自动调整掩码,因为它在测试中似乎更可靠,但如果需要,我可以在测试中使用自动调整掩码方法。
现在,当有人点击减号时,默认情况是视图被压扁。
我可以通过在设置我的手机时拨打电话来避免这种情况
subcontentView.contentMode = UIViewContentModeRedraw;
这给了我正确的最终结果(我的自定义视图以新大小重绘,并且布局正确,就像我发布的第一张图片一样),但是过渡的动画令人不快:它看起来像单元格拉伸和缩小到原来的大小。
我知道为什么动画会这样工作:Core Animation 不会要求您的视图重绘每一帧,它会让它重绘动画的结束位置,然后进行插值以找到中间位。
另一种解决方案是这样做
subcontentView.contentMode = UIViewContentModeLeft;
这只是在我的单元格上绘制了删除按钮,所以它覆盖了它的一部分。
如果我也实现
- (void) didTransitionToState:(UITableViewCellStateMask)state
[self setNeedsDisplay];
一旦删除按钮在单元格中滑动,就会“跳转”到正确的大小。这样就没有很好的滑动动画,但至少我最后得到了正确的结果。
我想我可以在删除按钮出现的同时运行我自己的动画,临时创建另一个视图,其中包含旧尺寸的视图图像的副本,将我的视图设置为新尺寸,并在它们之间淡入淡出——即这样会有一个很好的交叉淡入淡出而不是急剧跳跃。有人用过这种技术吗?
现在,您可能会问为什么我不能使用contentStretch
属性并给它一个区域来调整大小。问题是我正在做一些相当通用的东西,所以它并不总是可能的。在这个特定的示例中它可以工作,但更复杂的单元格可能不会。
所以,我的问题(在所有这些背景之后)是:在这种情况下你会做什么?有没有人有用于自定义绘制单元格的动画删除按钮?如果不是,最好的妥协是什么?
【问题讨论】:
我得到了它的工作,虽然我现在没有代码。可以私信我吗 【参考方案1】:这终于对我有用了。在 UITableViewCell 的子类中
subDrawContentView.contentMode = UIViewContentModeLeft;
覆盖布局子视图方法
- (void)layoutSubviews
CGRect b = [subDrawContentView bounds];
b.size.width = (!self.showingDeleteConfirmation) ? 320 : 300;
[subDrawContentView setFrame:b];
[subDrawContentView setNeedsDisplay];
[super layoutSubviews];
【讨论】:
【参考方案2】:所以我先贴代码再解释:
-(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];
所以我有一个如下所示的按钮:
我有一个IBOutlet
。我正在做的是调整UIProgressView
和UITextField
的大小(你可以调整任何你想要的大小)。至于代码非常简单,但是如果您需要任何帮助来了解发生了什么,请询问。另外,不要忘记将 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 :)
如您所见,整个动画是手动创建的,因此您可以准确控制您想要的内容。 :)
【讨论】:
以上是关于UITableViewCell 子类,在代码中绘制,动画中的删除按钮的主要内容,如果未能解决你的问题,请参考以下文章
子类 UITableViewCell - backgroundView 涵盖了我在 drawRect 中所做的任何事情
带有在代码中绘制的自定义图像的 UITableViewCell