UIButton flashing animation

后端 未结 5 2030
粉色の甜心
粉色の甜心 2021-02-03 15:20

I was wondering if it was possible to apply a flashing animation to a UIButton. I have searched but only found the code for a pulse animation which changes the size of my UIButt

相关标签:
5条回答
  • 2021-02-03 15:31

    I did this by creating my own control, subclassing UIControl since Apple doesn't recommend screwing with the view hierarchy of UIButton. I add a background imageView representing the standard background image of the button, and a "glowing" imageView above the background to represent the lit-up state, and toggle its opacity to make it pulse.

    I additionally toggle the layer's shadow opacity to make it glow.

    Initializing Code:

    - (void)TS_commonButtonInit
    {
        UIImage *shoutoutBackground            = [UIImage imageNamed:@"root-navigation-bar-share-button"];
        UIImage *shoutoutHighlightedBackground = [UIImage imageNamed:@"root-navigation-bar-share-button-highlighted"];
        UIImage *shoutoutPulseImage            = [UIImage imageNamed:@"root-navigation-bar-share-button-glowing"];
    
        shoutoutBackground            = [shoutoutBackground            stretchableImageWithLeftCapWidth:7 topCapHeight:0];
        shoutoutHighlightedBackground = [shoutoutHighlightedBackground stretchableImageWithLeftCapWidth:7 topCapHeight:0];
        shoutoutPulseImage            = [shoutoutPulseImage            stretchableImageWithLeftCapWidth:7 topCapHeight:0];
    
        [[self backgroundView] setImage:shoutoutBackground];
        [[self backgroundView] setHighlightedImage:shoutoutHighlightedBackground];
    
        [self setGlowingImage:shoutoutPulseImage];
    
        [self setExclusiveTouch:YES];
    
        [self addSubview:[self backgroundView]];
        [self addSubview:[self glowingImageView]];
    
        [[self layer] setShadowColor:[[UIColor colorWithHexString:@"ffc521" alpha:1] CGColor]];
        [[self layer] setShadowOpacity:0];
        [[self layer] setShadowRadius:5];
        [[self layer] setShadowOffset:CGSizeMake(0, 0)];
        [[self layer] setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:[self bounds] cornerRadius:6] CGPath]];
    }
    

    Pulsing Code:

    - (void)pulse:(NSInteger)numberOfTimes
    {
        CGFloat pulseLength = .8;
    
        [[self glowingImageView] setAlpha:0];
    
        CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        [pulseAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [pulseAnimation setDuration:pulseLength];
        [pulseAnimation setRepeatCount:numberOfTimes];
        [pulseAnimation setAutoreverses:YES];
        [pulseAnimation setFromValue:@(0)];
        [pulseAnimation setToValue:@(1)];
        [pulseAnimation setRemovedOnCompletion:YES];
    
        [[self layer] setShadowOpacity:0];
    
        CABasicAnimation *shadowAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
        [shadowAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [shadowAnimation setDuration:pulseLength];
        [shadowAnimation setRepeatCount:numberOfTimes];
        [shadowAnimation setAutoreverses:YES];
        [shadowAnimation setFromValue:@(0)];
        [shadowAnimation setToValue:@(1)];
        [shadowAnimation setRemovedOnCompletion:YES];
    
        [[[self glowingImageView] layer] addAnimation:pulseAnimation forKey:@"opacity"];
        [[self layer] addAnimation:shadowAnimation forKey:@"shadowOpacity"];
    }
    
    0 讨论(0)
  • 2021-02-03 15:36

    Try this one:

    call this method when you want blink/flash the button

    blinkTimer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(toggleButtonImage:) userInfo:nil repeats:YES];
    

    and write this method

    - (void)toggleButtonImage:(NSTimer*)timer
    {
    
        if(toggle)
        {
            [blinkBtn setImage:[UIImage imageNamed:@"ButtonImage.png"] forState: UIControlStateNormal];
        }
        else
        {
            [blinkBtn setImage:[UIImage imageNamed:@"ButtonImage1.png"] forState: UIControlStateNormal];
        }
        toggle = !toggle;
    
    }
    

    in .h write this one

    NSTimer *blinkTimer;
    BOOL toggle;
    

    and invalidate the timer where you want to stop the flashing/blinking

    [blinkTimer invalidate];
    
    0 讨论(0)
  • 2021-02-03 15:38

    Reading all the answers so far I found following solution. It repeats a number of times and does the job for me.

    CGFloat oldAlpha = v.alpha;
    CGFloat minAlpha = 0.2;
    enum UIViewAnimationOptions options = UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionCurveEaseInOut;
    
    [UIView animateWithDuration:.3 delay:0.3 options:options animations:^{
        [UIView setAnimationRepeatCount:4];
        v.alpha = minAlpha;
    }
    completion:^(BOOL finished) {
        v.alpha = oldAlpha;
    }];
    
    0 讨论(0)
  • 2021-02-03 15:47

    Perhaps not the best way, and doesn't really allow you to stop the flashing... but this is simple, works, and does not hinder user interaction:

    - (void)viewDidLoad
    {
        [self flashOn:myButton];
    }
    
    - (void)flashOff:(UIView *)v
    {
        [UIView animateWithDuration:.05 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^ {
            v.alpha = .01;  //don't animate alpha to 0, otherwise you won't be able to interact with it
        } completion:^(BOOL finished) {
            [self flashOn:v];
        }];
    }
    
    - (void)flashOn:(UIView *)v
    {
        [UIView animateWithDuration:.05 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^ {
            v.alpha = 1;
        } completion:^(BOOL finished) {
            [self flashOff:v];
        }];
    }
    
    0 讨论(0)
  • 2021-02-03 15:51

    Maybe you could have two different .png files [buttons] that cycle back and forth in a loop, assign the same action to them, and have this kick off whenever a certain condition is met. I'd write the code out but it would likely be full of errors. Have you tried something like that?

    0 讨论(0)
提交回复
热议问题