加入購物車動(dòng)畫

需求:

20161205170511736.png

點(diǎn)擊商品列表中正在售賣的商品,通過坐標(biāo)轉(zhuǎn)換和動(dòng)畫的方式,完成類似點(diǎn)贊動(dòng)畫、加入購物車、查看頭像大圖等效果。

思路及問題點(diǎn):

1)點(diǎn)擊cell中的的添加+或者減號(hào)-來完成加入購物車的動(dòng)畫事件,需要清楚用戶點(diǎn)擊的是哪一個(gè)cell上面的button,更新購物車數(shù)量等操作。

__weak typeof(self) this = self;
        cell.addGoodBlock = ^(ShopListGoodsCell *cell) {
            [this goodAddOrMinusAction:YES cell:cell];
            [cell updateCount];
        };
        cell.minusGoodBlock = ^(ShopListGoodsCell *cell) {
            [this goodAddOrMinusAction:NO cell:cell];
            [cell updateCount];
        };

2)坐標(biāo)系的轉(zhuǎn)換
將像素point由point所在視圖轉(zhuǎn)換到目標(biāo)視圖view中,返回在目標(biāo)視圖view中的像素值
這里我們要將一個(gè)位置坐標(biāo)傳出去,但是傳什么位置呢?如果是Lable的位置簡單的傳出去,那么很明顯會(huì)出現(xiàn)一個(gè)問題:不管你點(diǎn)擊那個(gè)cell的按鈕,動(dòng)畫都是從同一個(gè)起點(diǎn)出發(fā)的,而且絕對(duì)不會(huì)是任何正確的起點(diǎn)。因?yàn)槊總€(gè)cell中Label的位置都是一樣的,而我們實(shí)際需要的是這個(gè)坐標(biāo)相對(duì)于TableView的位置,也就是說它在父視圖中的位置,所以這里要將該點(diǎn)坐標(biāo)轉(zhuǎn)換。
右下角有一組圖片和按鈕,表示購物車,在tableView中有我們之前傳過來的坐標(biāo),而我們希望讓動(dòng)畫發(fā)生在view層級(jí)上,所以這里需要兩次坐標(biāo)轉(zhuǎn)換,把右下角的控件集合中的按鈕坐標(biāo)(購物車是個(gè)按鈕)和tableView中的傳過來的起點(diǎn)坐標(biāo)都轉(zhuǎn)換到self.view中,具體做法是:


if (cell) {
        CGRect startRect = [cell convertRect:cell.countLab.frame toView:self.navigationController.view];
        [self joinCartAnimationWithRect:startRect];
    } else {
        CGRect startRect = [self.goodDesView convertRect:self.countLab.frame toView:self.navigationController.view];
        [self joinCartAnimationWithRect:startRect];
    }
[self updateCount];

3)Bezier曲線的應(yīng)用
因?yàn)槲覀兿氘a(chǎn)生一種類拋物線的動(dòng)畫,所以這里我們需要二階Bezier曲線即可,所以要提供三個(gè)控制點(diǎn),起始點(diǎn)和終止點(diǎn)都已經(jīng)有了,關(guān)鍵就是中間的控制點(diǎn)。在計(jì)圖實(shí)驗(yàn)中生成Bezier時(shí),我們用的一種思路是以直代曲,用大量短線段來表示一條曲線,每一個(gè)n階Bezier曲線(n+1個(gè)點(diǎn))在生成時(shí),總能在n個(gè)線段中按照一個(gè)比例各找出一個(gè)點(diǎn),而這n個(gè)點(diǎn)又能生成一個(gè)n-1階Bezier,我們的Bezier曲線上的點(diǎn)就是當(dāng)只有一條線段以后按照那個(gè)比例找出的那個(gè)點(diǎn)。


UIView的動(dòng)畫是作用在layer層級(jí)的,所以我們可以生成一個(gè)CALayer,在這個(gè)layer上添加上自己的圖片,然后將動(dòng)畫應(yīng)用到這個(gè)layer中即可。

#pragma mark -加入購物車動(dòng)畫
-(void) joinCartAnimationWithRect:(CGRect)rect
{
//加入購物車結(jié)束點(diǎn)
    CGFloat endPoint_x = 35;
    CGFloat endPoint_y = SCREEN_HEIGHT - 35;
//加入購物車開始點(diǎn)
    CGFloat startX = rect.origin.x;
    CGFloat startY = rect.origin.y;// 和頭部差值
//繪制貝塞爾曲線
    UIBezierPath *path= [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(startX, startY)];
    
    //三點(diǎn)曲線 讓動(dòng)畫下滑的路線
    [path addCurveToPoint:CGPointMake(endPoint_x, endPoint_y)
            controlPoint1:CGPointMake(startX, startY)
            controlPoint2:CGPointMake(startX - 180, startY - 200)];
    CALayer *dotLayer = [CALayer layer];
    dotLayer.backgroundColor = [UIColor colorWithRed:244.0/255.0 green:80.0/255.0 blue:100.0/255.0 alpha:1].CGColor;
    dotLayer.frame = CGRectMake(0, 0, 16, 16);
    dotLayer.cornerRadius = 8;
    [self.view.layer addSublayer:dotLayer];
    [self groupAnimation:path.CGPath layer:dotLayer];
}
#pragma mark - 組合動(dòng)畫
-(void)groupAnimation:(CGPathRef)path layer:(CALayer*)layer;
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = path;
    animation.rotationMode = kCAAnimationRotateAuto;
    
    CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"alpha"];
    alphaAnimation.duration = 0.2f;
    alphaAnimation.fromValue = [NSNumber numberWithFloat:1.0];
    alphaAnimation.toValue = [NSNumber numberWithFloat:0.1];
    alphaAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    
    CAAnimationGroup *groups = [CAAnimationGroup animation];
    groups.animations = @[animation,alphaAnimation];
    groups.duration = 0.5f;
    groups.removedOnCompletion = NO;
    
    groups.fillMode = kCAFillModeForwards;
    groups.delegate = self;
    [groups setValue:@"groupsAnimation" forKey:@"animationName"];
    [layer addAnimation:groups forKey:nil];
    [self performSelector:@selector(removeFromLayer:) withObject:layer afterDelay:0.5f];
}

- (void)removeFromLayer:(CALayer *)layerAnimation{
    
    [layerAnimation removeFromSuperlayer];
}

#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    //[self performSelector:@selector(removeFromLayer:) withObject:dotLayer afterDelay:0.8f];
    if ([[anim valueForKey:@"animationName"]isEqualToString:@"groupsAnimation"]) {
        
        CABasicAnimation *shakeAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        shakeAnimation.duration = 0.25f;
        shakeAnimation.fromValue = [NSNumber numberWithFloat:0.9];
        shakeAnimation.toValue = [NSNumber numberWithFloat:1];
        shakeAnimation.autoreverses = YES;
        //這個(gè)是下方的自定義View上面放的btn
        [self.cardView.cartBtn.layer addAnimation:shakeAnimation forKey:nil];
        
    }
    
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容