iOS仿美团外卖饿了吗App点餐动画

这里写图片描述
前言: 在这篇文章中你可以学到什么? Masonry布局, Block 以及动画, 俗称的懒加载. (想了解的看一看). 0.-

tableViewCell布局篇–为方便大家查看, 我会尽量贴出全部代码

/**< typedef block >*/
typedef void(^btnPulsBlock)(NSInteger count, BOOL animated);
@interface XTFoodCell : UITableViewCell
@property (nonatomic, strong) UIImageView *foodImage;   // cyan
@property (nonatomic, strong) UILabel *nameLabel;       // orange
@property (nonatomic, strong) UILabel *priceLabel;      // gray
@property (nonatomic, strong) UIButton *btnMinus;       // black
@property (nonatomic, strong) UIButton *btnPlus;        // black
@property (nonatomic, strong) UILabel *orderCount;      // red
@property (nonatomic, copy)   btnPulsBlock block;       // block
@property (nonatomic, strong) UIImageView *animateView; // 购物车图标
@property (nonatomic, assign) NSInteger numCount;       // 计数器
@end

.m 实现篇

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self createSubviews];
    }
    return self;
}
- (void)createSubviews
{
    [self.contentView addSubview:self.foodImage];
    [self.contentView addSubview:self.nameLabel];
    [self.contentView addSubview:self.priceLabel];
    [self.contentView addSubview:self.btnMinus];
    [self.contentView addSubview:self.btnPlus];
    [self.contentView addSubview:self.orderCount];
}
- (UIImageView *)foodImage
{
    if (!_foodImage) {
        _foodImage = [[UIImageView alloc] init];
    }
    return _foodImage;
}
- (UILabel *)nameLabel
{
    if (!_nameLabel) {
        _nameLabel = [[UILabel alloc] init];
    }
    return _nameLabel;
}
- (UILabel *)priceLabel
{
    if (!_priceLabel) {
        _priceLabel = [[UILabel alloc] init];
    }
    return _priceLabel;
}
- (UIButton *)btnMinus
{
    if (!_btnMinus) {
        _btnMinus = [UIButton buttonWithType:UIButtonTypeCustom];
    }
    return _btnMinus;
}
- (UIButton *)btnPlus
{
    if (!_btnPlus) {
        _btnPlus = [UIButton buttonWithType:UIButtonTypeCustom];
    }
    return _btnPlus;
}
- (UILabel *)orderCount
{
    if (!_orderCount) {
        _orderCount = [[UILabel alloc] init];
    }
    return _orderCount;
}

UI布局篇–Masonry

- (void)layoutSubviews
{
    [super layoutSubviews];
    [_foodImage mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.mas_top).with.offset(5.0);
        make.left.equalTo(self.contentView.mas_left).with.offset(5.0);
        make.width.equalTo(@88.0);
        make.height.equalTo(@88.0);
    }];
    self.foodImage.backgroundColor = [UIColor cyanColor];

    [_nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.foodImage.mas_right).with.offset(5.0);
        make.top.equalTo(self.contentView.mas_top).with.offset(5.0);
        make.right.equalTo(self.contentView.mas_right).with.offset(-5.0);
        make.height.equalTo(@30);
    }];
    self.nameLabel.backgroundColor = [UIColor orangeColor];

    [_priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_nameLabel);
        make.width.equalTo(@50.0);
        make.height.equalTo(@30);
        make.bottom.equalTo(self.contentView.mas_bottom).with.offset(-5.0);
    }];
    self.priceLabel.backgroundColor = [UIColor lightGrayColor];

    [_btnMinus mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(_nameLabel);
        make.centerY.equalTo(self.contentView);
        make.width.height.mas_equalTo(CGSizeMake(25, 25));
    }];
    self.btnMinus.backgroundColor = [UIColor blackColor];

    [_orderCount mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_btnMinus.mas_right).with.offset(10);
        make.centerY.equalTo(self.contentView);
        make.width.height.mas_equalTo(CGSizeMake(35, 25));
    }];
    self.orderCount.backgroundColor = [UIColor redColor];

    [self.btnPlus mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_orderCount.mas_right).with.offset(10);
        make.centerY.equalTo(self.contentView);
        make.width.height.mas_equalTo(CGSizeMake(25, 25));
    }];
    self.btnPlus.backgroundColor = [UIColor blackColor];

    [_btnMinus setTitle:@"减" forState:UIControlStateNormal];
    [_btnMinus addTarget:self action:@selector(clickMin:) forControlEvents:UIControlEventTouchUpInside];
    _btnMinus.hidden = YES;

    [_btnPlus setTitle:@"加" forState:UIControlStateNormal];
    [_btnPlus addTarget:self action:@selector(clickPuls:) forControlEvents:UIControlEventTouchUpInside];   
}

btn点击方法–

- (void)clickPuls:(UIButton *)btn
{
    self.numCount += 1;
    self.block(self.numCount, YES);
    [self showOrderNums:self.numCount];

}
- (void)clickMin:(UIButton *)btn
{
    self.numCount -= 1;
    self.block(self.numCount, NO);
    [self showOrderNums:self.numCount];
}

VC篇– 这里给出cellForRowAtIndexPath中代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    XTFoodCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    // Block 回调
    __weak __typeof(&*cell) weakCell = cell;
    cell.block = ^(NSInteger nCount, BOOL boo){

        CGRect parentRect = [weakCell convertRect:weakCell.btnPlus.frame toView:self.view];

        if (boo) {
            // 这里是动画开始的方法
            [self JoinCartAnimationWithRect:parentRect];

        }
        else
        {

        }
    };
    return cell;
}
#pragma mark -加入购物车动画
-(void) JoinCartAnimationWithRect:(CGRect)rect
{
    _endPoint_x = 35;
    _endPoint_y = Screen_height - 35;

    CGFloat startX = rect.origin.x;
    CGFloat startY = rect.origin.y;

    _path= [UIBezierPath bezierPath];
    [_path moveToPoint:CGPointMake(startX, startY)];

    //三点曲线
    [_path addCurveToPoint:CGPointMake(_endPoint_x, _endPoint_y)
             controlPoint1:CGPointMake(startX, startY)
             controlPoint2:CGPointMake(startX - 180, startY - 200)];
    _dotLayer = [CALayer layer];
    _dotLayer.backgroundColor = [UIColor purpleColor].CGColor;
    _dotLayer.frame = CGRectMake(0, 0, 20, 20);
    _dotLayer.cornerRadius = 5;
    [self.view.layer addSublayer:_dotLayer];
    [self groupAnimation];   
}
#pragma mark - 组合动画
-(void)groupAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = _path.CGPath;
    animation.rotationMode = kCAAnimationRotateAuto;

    CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"alpha"];
    alphaAnimation.duration = 0.5f;
    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.8f;
    groups.removedOnCompletion = NO;
    groups.fillMode = kCAFillModeForwards;
    groups.delegate = self;
    [groups setValue:@"groupsAnimation" forKey:@"animationName"];
    [_dotLayer addAnimation:groups forKey:nil];
    [self performSelector:@selector(removeFromLayer:) withObject:_dotLayer afterDelay:0.8f];   
}
- (void)removeFromLayer:(CALayer *)layerAnimation{

    [layerAnimation removeFromSuperlayer];
}

CAAnimationDelegate–

#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{

    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;
        // 这里是下方的自定义View上面 放的btn. 自己随便定义一个 0.- 
        [_shopCartView.btnBackImg.layer addAnimation:shakeAnimation forKey:nil];

}

基本就是全部代码了.

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值