Как сделать мигающий (или мигающий) курсор на 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];
}
Ответы
Ответ 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.
Обратите внимание, что любая такая постоянная анимация, как это, приведет к утечке батареи. Не огромный, каким-либо образом, но... все же...