如何创建不断增长的iOS按钮?

时间:2016-04-12 18:02:34

标签: ios objective-c animation uibutton

我的朋友给了我以下iOS按钮的设计,我不确定实现它的最佳方法。

我需要制作如下所示的可重复使用按钮(在Objective-C中)。

我试过了:

  • 对按钮进行子类化,但请阅读shouldn't do that
  • 动画边框(虽然是子类),但边框只向内,所以我似乎需要为框架设置动画

那我该怎么做呢?我假设制作一个CustomButtonView类,它有一个按钮(组合)以及一个内外圆视图?然后,我将如何制作动画以增长?我是否还必须为帧更改设置动画,还是可以使用insets?

使这项工作最简单的代码是什么?谢谢!

Growing Buttons

1 个答案:

答案 0 :(得分:1)

这是我采取的方法来创建这个:

ButtonAnimation

  1. 用于创建自定义按钮的子类UIView
  2. 使用UITapGestureRecognizertouchesBegantouchesEnded ...进行互动
  3. 为您的前景和背景图层添加两个CALayer
  4. 添加图标图层(可以是UIImageView或任何其他显示图像的方式)

    - (id)initWithIcon:(UIImage *)icon backgroundColor:(UIColor *)backgroundColor foregroundColor:(UIColor *)foregroundColor {
    
        if (self = [super init]) {
            // Background Layer Setup
            _backgroundLayer = [CALayer new];
            [_backgroundLayer setBackgroundColor:backgroundColor.CGColor];
            [self.layer addSublayer:_backgroundLayer];
    
            // Foreground Layer Setup
            _foregroundLayer = [CALayer new];
            [_foregroundLayer setBackgroundColor:foregroundColor.CGColor];
            [self.layer addSublayer:_foregroundLayer];
    
            // Icon Setup
            _icon = [[UIImageView alloc] initWithImage:icon];
            [_icon setContentMode:UIViewContentModeCenter];
            [self addSubview:_icon];
    
            UIGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(buttonTapped:)];
            [self addGestureRecognizer:tapGesture];
        }
        return self;
    }
    
    - (void)setFrame:(CGRect)frame {
    
        // Make sure super is called
        [super setFrame:frame];
    
        // Build the layout of backgroundLayer
        [self.backgroundLayer setFrame:CGRectMake(frame.size.width*0.1, frame.size.width*0.1, frame.size.width*0.8, frame.size.width*0.8)];
        [self.backgroundLayer setCornerRadius:frame.size.width*0.8/2];
    
        // Build the layout of forgroundLayer
        [self.foregroundLayer setFrame:CGRectMake(frame.size.width*0.05, frame.size.width*0.05, frame.size.width*0.9, frame.size.width*0.9)];
        [self.foregroundLayer setCornerRadius:frame.size.width*0.9/2];
    
        // Build the frame of your icon
        [self.icon setFrame:CGRectMake(0, 0, frame.size.width, frame.size.width)];
    }
    
    - (void)buttonTapped:(UIGestureRecognizer*)gesture {
    
        // Animate the foreground getting smaller
        CABasicAnimation *foregroundFrameChange = [CABasicAnimation animationWithKeyPath:@"frame"];
        foregroundFrameChange.fromValue = [NSValue valueWithCGRect:_foregroundLayer.frame];
        foregroundFrameChange.toValue   = [NSValue valueWithCGRect:CGRectMake(self.frame.size.width*0.1,self.frame.size.width*0.1, self.frame.size.width*0.8, self.frame.size.width*0.8)];
        self.foregroundLayer.frame = CGRectMake(self.frame.size.width*0.1,self.frame.size.width*0.1, self.frame.size.width*0.8, self.frame.size.width*0.8);
    
        // Animate the forground cornerRadius to stay rounded
        CABasicAnimation *foregroundRadiusChange = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
        foregroundRadiusChange.fromValue = [NSNumber numberWithDouble:self.foregroundLayer.cornerRadius];
        foregroundRadiusChange.toValue   = [NSNumber numberWithDouble:self.frame.size.width*0.8/2];
        [self.foregroundLayer setCornerRadius:self.frame.size.width*0.8/2];
    
        // Animate the background getting larger
        CABasicAnimation *backgroundFrameChange = [CABasicAnimation animationWithKeyPath:@"frame"];
        backgroundFrameChange.fromValue = [NSValue valueWithCGRect:self.backgroundLayer.frame];
        backgroundFrameChange.toValue   = [NSValue valueWithCGRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.width)];
        self.backgroundLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.width);
    
        // Animate the background cornerRadius to stay rounded
        CABasicAnimation *backgroundRadiusChange = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
        backgroundRadiusChange.fromValue = [NSNumber numberWithDouble:self.backgroundLayer.cornerRadius];
        backgroundRadiusChange.toValue   = [NSNumber numberWithDouble:self.frame.size.width/2];
        [self.backgroundLayer setCornerRadius:self.frame.size.width/2];
    
        // Group all the animations to run simultaneously
        CAAnimationGroup *allAnimations = [CAAnimationGroup animation];
        allAnimations.duration   = 2;
        allAnimations.animations = @[foregroundFrameChange, foregroundRadiusChange, backgroundFrameChange, backgroundRadiusChange];
        allAnimations.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [self.layer addAnimation:allAnimations forKey:@"animate"];
    
        // Create your button action callback here
    }
    

    这是一个快速模拟,而不是一个完整的解决方案,但它会给你一些东西。