我正在开发一个自定义的UITableViewCell子类,其中所有内容都是用代码绘制的,而不是使用UILabels等。(这是部分学习练习,部分原因是代码绘制速度要快得多。我知道有几个标签它不会产生巨大的差异,但最终我想把它推广到更复杂的细胞。)
目前我正在努力使用删除按钮动画:如何在删除按钮滑入时为单元缩小设置动画。
首先,我正在绘制单元格contentView的自定义子视图。一切都是在那个子视图中绘制的。
我通过在单元格本身上捕捉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
属性并为其指定一个区域来调整大小。问题是我正在做一些合理的通用,所以它并不总是可行的。在这个特定的例子中,它可以工作,但更复杂的单元可能不会。
所以,我的问题(在所有这些背景之后)是:你在这种情况下做了什么?有没有人有自定义绘制单元格的动画删除按钮?如果没有,最好的妥协是什么?
答案 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];
}
}
所以我有一个看起来像这样的按钮:
我有一个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 :)
}
}
}
因此,您可以看到整个动画是手动创建的,因此您可以准确控制所需内容。 :)