Отмена анимации UIView?

голоса
221

Можно ли отменить UIViewанимацию в то время как он находится в стадии разработки ? Или я должен упасть до уровня СА?

то, что я сделал что-то вроде этого (возможно установки анимационного действия торцевого тоже):

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

Но до того, как анимация завершается, и я получаю анимации закончился событие, я хочу, чтобы отменить его (вырезать его коротким). Это возможно? Погуглить вокруг находит несколько людей задают тот же вопрос, без ответа - и один или два человека, полагает, что это не может быть сделано.

Задан 17/02/2009 в 00:19
источник пользователем
На других языках...                            


17 ответов

голоса
342

Использование:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];
Ответил 19/03/2010 в 07:53
источник пользователем

голоса
111

Как мне это сделать, чтобы создать новую анимацию к конечной точке маршрута . Установить очень короткую продолжительность и убедитесь , что вы используете +setAnimationBeginsFromCurrentState:метод для запуска из текущего состояния. Когда вы установите его в YES, текущая анимация обрывается. Выглядит примерно так:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];
Ответил 08/05/2009 в 22:46
источник пользователем

голоса
61

Простейший способ остановить все анимации на определенную точку зрения, сразу же , заключается в следующем:

Ссылка на проект в QuartzCore.framework. В начале вашего кода:

#import <QuartzCore/QuartzCore.h>

Теперь, когда вы хотите, чтобы остановить все анимации на представлении мертвых в своих треках, скажем так:

[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];

Средняя линия будет работать сама по себе, но есть задержка, пока runloop отделок (далее «перерисовывать момент»). Чтобы предотвратить эту задержку, завернуть команду в явном блоке транзакции, как показано на рисунке. Это работы не предусмотрено никаких других изменений были выполнены на этом уровне в текущем runloop.

Ответил 04/01/2012 в 00:03
источник пользователем

голоса
43

КСН 4 и более, используйте UIViewAnimationOptionBeginFromCurrentStateопцию на второй анимации вырезать первую анимацию коротким.

В качестве примера, предположим , что у вас есть вид с индикатором активности. Вы хотите , чтобы исчезнуть в индикаторе активности , а некоторые потенциально времени активности начинается, и постепенно исчезать, когда деятельность закончена. В коде ниже, вид с индикатором активности на нем называется activityView.

- (void)showActivityIndicator {
    activityView.alpha = 0.0;
    activityView.hidden = NO;
    [UIView animateWithDuration:0.5
                 animations:^(void) {
                     activityView.alpha = 1.0;
                 }];

- (void)hideActivityIndicator {
    [UIView animateWithDuration:0.5
                 delay:0 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^(void) {
                     activityView.alpha = 0.0;
                 }
                 completion:^(BOOL completed) {
                     if (completed) {
                         activityView.hidden = YES;
                     }
                 }];
}
Ответил 11/08/2011 в 09:30
источник пользователем

голоса
39

Чтобы отменить анимацию просто нужно установить свойство, что в настоящее время анимированное, вне анимации UIView. Это будет остановить анимацию, где она есть, и UIView будет переходить к настройке вы просто определили.

Ответил 19/06/2010 в 18:09
источник пользователем

голоса
9

Если вы оживляющее ограничение, изменив константу вместо вида собственности ни один из других методов работы на прошивке 8.

Пример анимации:

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

Решение:

Вы должны удалить анимацию из слоев любых взглядов под воздействием изменения ограничений и их подслои.

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}
Ответил 07/11/2014 в 17:21
источник пользователем

голоса
8

К сожалению воскресить этот ответ, но в ИО 10 вещей, своего рода изменилось, и теперь можно отменить, и вы можете даже отменить грациозно!

После прошивки 10 вы можете отменить анимацию с UIViewPropertyAnimator !

UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
    view.backgroundColor = .blue
})
animator.stopAnimation(true)

Если вы передадите это верно отменяет анимацию и останавливается прямо там, где вы его отменили. Метод завершения не будет вызываться. Тем не менее, если вы передаете ложь вы ответственны за окончание анимации:

animator.finishAnimation(.start)

Вы можете закончить анимацию и остаться в текущем состоянии (.current) или перейти в исходное состояние (.start) или до конечного состояния (.end)

Кстати, вы можете даже сделать паузу и перезапустить позже ...

animator.pauseAnimation()
animator.startAnimation()

Примечание: Если вы не хотите, скачкообразные отмен можно отменить анимацию или даже изменить анимацию после приостановки его!

Ответил 09/11/2017 в 17:57
источник пользователем

голоса
7

Если вы просто хотите, чтобы приостановить / остановить анимацию гладко

self.yourView.layer.speed = 0;

Источник: Как приостановить анимацию дерева слоя

Ответил 29/06/2015 в 11:02
источник пользователем

голоса
5
[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];
Ответил 06/02/2015 в 05:30
источник пользователем

голоса
5

Ни один из вышеперечисленных не решил это для меня, но это помогло: UIViewанимация устанавливает свойство сразу, затем оживляет его. Он останавливает анимацию , когда уровень представления соответствует модели (набор свойств).

Я решить мою проблему, которая была «Я хочу, чтобы оживить, где вы смотрите, как вы оказываетесь» ( «вы» означает вид). Если вы хотите этого, то:

  1. Добавить QuartzCore.
  2. CALayer * pLayer = theView.layer.presentationLayer;

установить позицию на уровне представления

Я использую несколько вариантов, включая UIViewAnimationOptionOverrideInheritedDuration

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

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

И это должно быть приличным решением на данный момент.

Ответил 16/08/2011 в 18:21
источник пользователем

голоса
1

У меня такая же проблема; API-интерфейсы не имеют ничего, чтобы отменить некоторые конкретные анимации.

+ (void)setAnimationsEnabled:(BOOL)enabled

отключает все анимации, и, таким образом, не работает для меня. Там в два решения:

1) сделать свой анимированный объект подвида. Затем, когда вы хотите, чтобы отменить анимацию для этой точки зрения, удалить вид или скрыть его. Очень просто, но вам нужно воссоздать подвид без анимации, если вам нужно, чтобы держать его в поле зрения.

2) повторить Анят только один, и сделать селектор делегата для перезапуска Анит, если это необходимо, например:

-(void) startAnimation {
NSLog(@"startAnim alpha:%f", self.alpha);
[self setAlpha:1.0];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(pulseAnimationDidStop:finished:context:)];
[self setAlpha:0.1];
[UIView commitAnimations];
}

- (void)pulseAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
if(hasFocus) {
    [self startAnimation];
} else {
    self.alpha = 1.0;
}
}

-(void) setHasFocus:(BOOL)_hasFocus {
hasFocus = _hasFocus;
if(hasFocus) {
    [self startAnimation];
}
}

Проблема с 2) является то, что там всегда задержит остановок Анят как он завершает текущий цикл анимации.

Надеюсь это поможет.

Ответил 08/05/2009 в 18:03
источник пользователем

голоса
0

Ни один из отвеченных решений не работает для меня. Я решил мои проблемы , таким образом (я не знаю , если это правильный путь?), Потому что у меня были проблемы , когда называют это слишком быстро (если предыдущая анимация еще не был завершен). Я передаю мою разыскиваемую анимацию с customAnim блоком.

extension UIView
{

    func niceCustomTranstion(
        duration: CGFloat = 0.3,
        options: UIView.AnimationOptions = .transitionCrossDissolve,
        customAnim: @escaping () -> Void
        )
    {
        UIView.transition(
            with: self,
            duration: TimeInterval(duration),
            options: options,
            animations: {
                customAnim()
        },
            completion: { (finished) in
                if !finished
                {
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    self.layer.removeAllAnimations()
                    customAnim()
                }
        })

    }

}
Ответил 20/08/2019 в 14:52
источник пользователем

голоса
0

Когда я работаю с UIStackViewанимацией, кроме того , removeAllAnimations()мне нужно установить некоторые значения в исходном , так как removeAllAnimations()можно установить их в непредсказуемое состояние. У меня есть stackViewс view1и view2внутри, и один вид должен быть виден и один скрытый:

public func configureStackView(hideView1: Bool, hideView2: Bool) {
    let oldHideView1 = view1.isHidden
    let oldHideView2 = view2.isHidden
    view1.layer.removeAllAnimations()
    view2.layer.removeAllAnimations()
    view.layer.removeAllAnimations()
    stackView.layer.removeAllAnimations()
    // after stopping animation the values are unpredictable, so set values to old
    view1.isHidden = oldHideView1 //    <- Solution is here
    view2.isHidden = oldHideView2 //    <- Solution is here

    UIView.animate(withDuration: 0.3,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                    view1.isHidden = hideView1
                    view2.isHidden = hideView2
                    stackView.layoutIfNeeded()
    },
                   completion: nil)
}
Ответил 07/02/2019 в 09:03
источник пользователем

голоса
0

Swift версия решения Стивена Дарлингтона

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()
Ответил 26/12/2017 в 15:09
источник пользователем

голоса
0

Чтобы приостановить анимацию без обращения государства к оригиналу или окончательным:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;
Ответил 03/12/2015 в 21:43
источник пользователем

голоса
0
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];
Ответил 28/01/2013 в 15:54
источник пользователем

голоса
0

Даже если отменить анимацию в анимации выше способов до didStopSelectorсих пор работает. Так что если у вас есть логические состояния в приложении приводится в анимации вы будете иметь проблемы. По этой причине с описанными выше способами я использую контекстные переменную UIViewанимацию. Если передать текущее состояние программы в контексте парам к анимации, когда анимация прекращается ваша didStopSelectorфункция может решить , если он должен сделать что - то или просто вернуться на основе текущего состояния и государственного значения , переданного в качестве контекста.

Ответил 05/10/2010 в 09:52
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more