Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a blinking (or flashing) cursor on iphone?

I'm trying to create a custom "blinking cursor" in UIKit, I've tried as shown below, having 2 functions that basically keep calling each other until the cursor is hidden. But this leads to a nice infinite recursion... for some reason the functions call each other right away, not each half-second as expected.

I tried returning if the 'finished' parameter is not YES (by uncommenting the 'if (!ok)' line), but that leads to no animation at all...

Any better idea? Did I miss something, is there a much-easier way to make a "blinking cursor"?

- (void)onBlinkIn:(NSString *)animationID finished:(BOOL)ok context:(void *)ctx {
if (cursorView.hidden) return;
//if (!ok) return;
[UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(onBlinkOut:finished:context:)];
cursorView.textColor = [UIColor grayColor];
[UIView commitAnimations];
}

- (void)onBlinkOut:(NSString *)animationID finished:(BOOL)ok context:(void *)ctx {
if (cursorView.hidden) return;
[UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(onBlinkIn:finished:context:)];
cursorView.textColor = [UIColor clearColor];
[UIView commitAnimations];
}
like image 902
Zoran Simic Avatar asked Sep 25 '09 09:09

Zoran Simic


People also ask

What is the meaning of blinking cursor?

Alternatively referred to as a caret, a cursor or text cursor is a blinking horizontal or vertical line ( ) that indicates where new text starts when you begin to type.


3 Answers

Do it the Core Animation way:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[animation setFromValue:[NSNumber numberWithFloat:1.0]];
[animation setToValue:[NSNumber numberWithFloat:0.0]];
[animation setDuration:0.5f];
[animation setTimingFunction:[CAMediaTimingFunction
              functionWithName:kCAMediaTimingFunctionLinear]];
[animation setAutoreverses:YES];
[animation setRepeatCount:20000];
[[view layer] addAnimation:animation forKey:@"opacity"];

Where view is the UIView you want to blink. Core Animation makes this very convenient because it will auto reverse the animation for you. Keep in mind that your complete duration is double what you set in the duration field because the value you specify applies to the forward direction. If you want the whole animation to run (forward and then back) in the specified duration, split the duration in half.

like image 171
Matt Long Avatar answered Sep 24 '22 17:09

Matt Long


On the delegate:

- (void)blinkAnimation:(NSString *)animationId finished:(BOOL)finished target:(UIView *)target
{
    if (shouldContinueBlinking) {
        [UIView beginAnimations:animationId context:target];
        [UIView setAnimationDuration:0.5f];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(blinkAnimation:finished:target:)];
        if ([target alpha] == 1.0f)
            [target setAlpha:0.0f];
        else
            [target setAlpha:1.0f];
        [UIView commitAnimations];
    }
}

And to start the animation:

shouldContinueBlinking = YES;
[self blinkAnimation:@"blinkAnimation" finished:YES target:cursorView];

Also, ensure your class has a shouldContinueBlinking instance variable

like image 40
rpetrich Avatar answered Sep 22 '22 17:09

rpetrich


Matt Long's answer in Swift 4:

func addOpacityAnimation(view: UIView) {
    let key = "opacity"
    let animation = CABasicAnimation(keyPath: key)
    animation.fromValue = 1.0
    animation.toValue = 0.0
    animation.duration = 0.5
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.autoreverses = true
    animation.repeatCount = Float.greatestFiniteMagnitude
    view.layer.add(animation, forKey: key)
}
like image 5
Bart van Kuik Avatar answered Sep 26 '22 17:09

Bart van Kuik