滚动时动画子视图删除冻结
Posted
技术标签:
【中文标题】滚动时动画子视图删除冻结【英文标题】:Animation subview removal freezes when scrolling 【发布时间】:2016-01-04 00:24:59 【问题描述】:我的代码:
我正在使用以下代码添加到购物篮动画:
-(void)triggerAddItemAnimation:(NSIndexPath*)indexPath
//Cell that was pressed.
CellMenuItem *cell = [self.tableView cellForRowAtIndexPath:indexPath];
// grab the imageview using cell
UIImageView *imgV = (UIImageView*)[cell viewWithTag:IDENTIFIER_ANIMATION_IMAGE];
//Get the x-coordinate of the image.
int xCoord = cell.imgAddButton.frame.origin.x;
// get the exact location of image
CGRect rect = [imgV.superview convertRect:imgV.frame fromView:nil];
rect = CGRectMake(xCoord, (rect.origin.y*-1)-10, imgV.frame.size.width, imgV.frame.size.height);
//NSLog(@"rect is %f,%f,%f,%f",rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
// create new duplicate image
UIImageView *starView = [[UIImageView alloc] initWithImage:imgV.image];
[starView setFrame:rect];
starView.layer.cornerRadius=5;
starView.layer.borderColor=[[UIColor blackColor]CGColor];
starView.layer.borderWidth=1;
[self.view addSubview:starView];
// begin ---- apply position animation
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration=0.65;
pathAnimation.delegate=self;
// tab-bar right side item frame-point = end point
CGPoint endPoint = CGPointMake(self.lblBasketItemsCount.frame.origin.x, self.lblBasketItemsCount.frame.origin.y);
CGMutablePathRef curvedPath = CGPathCreateMutable();
CGPathMoveToPoint(curvedPath, NULL, starView.frame.origin.x, starView.frame.origin.y);
CGPathAddCurveToPoint(curvedPath, NULL, endPoint.x, starView.frame.origin.y, endPoint.x, starView.frame.origin.y, endPoint.x, endPoint.y);
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);
// end ---- apply position animation
float animationDuration = 0.65f;
// apply transform animation
CABasicAnimation *basic=[CABasicAnimation animationWithKeyPath:@"transform"];
[basic setToValue:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.25, 0.25, 0.25)]];
[basic setAutoreverses:NO];
[basic setDuration:animationDuration];
[starView.layer addAnimation:pathAnimation forKey:@"curveAnimation"];
[starView.layer addAnimation:basic forKey:@"transform"];
//Remove the animation 0.05 before the animationDuration to remove clipping issue.
[starView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:animationDuration - 0.05f];
问题:
动画效果很好,但是当我滚动时,用于动画的图像(取自单元格)在滚动停止之前不会从视图中移除。
被移除的子视图与方法中的最后一行代码一起被移除:
[starView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:animationDuration - 0.05f];
我尝试过的:
我尝试过使用 GCD:
dispatch_async(dispatch_get_main_queue(), ^
//call method here....
);
如果我记得我相信我也尝试过带计时器的运行循环,以及在主线程上执行选择器。
我也试过把方法放在一个块中(不是我使用的实际代码,只是一个例子):
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^
completion:^(BOOL finished)
//Remove subview here
];
问题:
我可以推断出滚动占用了主线程,因此我尝试异步调用该方法。
谁能告诉我我做错了什么?
【问题讨论】:
【参考方案1】:要解决此问题,您可以使用块的完整部分,如上所示。我当时只是错误地使用了该块。
但是我解决这个问题的方法是,因为我无法让路径动画在块中工作,所以我将动画的委托设置为 self。
并使用以下内容:
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
[theView removeFromSuperview];
【讨论】:
以上是关于滚动时动画子视图删除冻结的主要内容,如果未能解决你的问题,请参考以下文章
调整滚动视图框架的大小时,UIScrollView 子视图的大小调整不正确