Подтвердить что ты не робот

Как сделать мигающий (или мигающий) курсор на iphone?

Я пытаюсь создать пользовательский "мигающий курсор" в UIKit, я пробовал, как показано ниже, с двумя функциями, которые в основном продолжают звонить друг другу, пока курсор не будет скрыт. Но это приводит к приятной бесконечной рекурсии... по какой-то причине функции сразу называют друг друга, а не каждую половину секунды, как ожидалось.

Я попытался вернуться, если параметр "закончен" не равен YES (раскомментируя строку "if (! ok)", но это вообще не приводит к анимации...

Любая лучшая идея? Я что-то пропустил, есть ли гораздо более простой способ сделать "мигающий курсор"?

- (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];
}
4b9b3361

Ответ 1

На делегате:

- (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];
    }
}

И для начала анимации:

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

Кроме того, убедитесь, что ваш класс имеет переменную экземпляра shouldContinueBlinking

Ответ 2

Сделайте это с помощью Core Animation:

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"];

Где вид - это UIView, который вы хотите мигать. Core Animation делает это очень удобным, потому что это автоматически изменит анимацию для вас. Имейте в виду, что ваша полная продолжительность удваивается, что вы установили в поле продолжительности, потому что указанное вами значение относится к прямому направлению. Если вы хотите, чтобы вся анимация запускалась (вперед, а затем назад) в заданную продолжительность, разделите продолжительность пополам.

Ответ 3

Ответ Мэтта Лонга в Swift 3:

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 = FLT_MAX
    view.layer.add(animation, forKey: key)
}

Ответ 4

Скорее всего, вы блокируете основной цикл событий и, таким образом, блокируете анимацию, когда вы пытаетесь только анимировать на финише.

Вместо этого настройте таймер, который срабатывает через 1/2 секунды, который запускает следующую анимацию. Этот таймер может быть reset в конце предыдущей анимации, таким образом уменьшая нагрузку и делая вашу скорость мигания немного более регулярной (но вам нужно будет выяснить, что наиболее подходит).

См. документацию по классу NSTimer.

Обратите внимание, что любая такая постоянная анимация, как это, приведет к утечке батареи. Не огромный, каким-либо образом, но... все же...