【问题标题】:Repeat the delay in a UIView animation loop?在 UIView 动画循环中重复延迟?
【发布时间】:2013-06-05 07:10:05
【问题描述】:

我正在尝试对视图不透明度进行自定义动画,如下所示:

  1. 延迟 5 秒; (视图将保持不透明 5 秒)
  2. 从不透明度值 1 变为 0 的动画;
  3. 延迟 5 秒; (视图将保持透明 5 秒)
  4. 从不透明度值 0 到 1 的动画;

我想无限期地重复步骤 1 到 4:1、2、3、4、1、2、3、4,.....

这是我尝试过的:

[UIView animateWithDuration:1
                      delay:5
                    options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat|UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     self.imageView.layer.opacity = 0;
                 }
                 completion:nil
 ];

但延迟只在开始时出现过一次,我最终得到的是:

1、2、4、2、4、2、4,.....

【问题讨论】:

    标签: ios uiview delay uiviewanimation repeat


    【解决方案1】:

    我遇到了同样的问题。我用这种方式解决了,使用 NSTimer

    [NSTimer scheduledTimerWithTimeInterval: 2
                                         target: self
                                       selector:@selector(moveImage: )
                                       userInfo: nil repeats:YES];
    
    
    }
    
    
    
    -(void) moveImage: (NSTimer*)timer {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2];
    

    【讨论】:

    • 注意这可能会导致内存泄漏,scheduledTimerWithTimeInterval 持有对target 的强引用,如果计时器从不失效,它将永远持有这个引用。
    【解决方案2】:

    @user1980004 感谢 NSTimer 的提示。我将发布我的问题的完整工作代码:

    // interface
    @property (strong, nonatomic) IBOutlet UIImageView *imageView;
    @property (strong, nonatomic) NSTimer *animationTimer;
    
    -(void) viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
        [self glowAnimation]; // Timer fires after a delay, so I need to fire animation for the first time
    
        // The interval value is determined by the sum of delay and duration for both the forward and reverse animation in glowAnimation function;
        self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:12 target:self selector:@selector(glowAnimation) userInfo:nil repeats:YES];
    }
    
    -(void) viewWillDisappear:(BOOL)animated{
        [super viewWillDisappear:animated];
    
        if (self.animationTimer){ 
            [self.animationTimer invalidate]; // Cancel the timer schedule
            self.animationTimer = nil;
        }
    }
    
    -(void) glowAnimation{
        // Forward and reverse animation are chained with delay in each.
        [UIView animateWithDuration:1
                              delay:5
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^{
                             self.imageView.layer.opacity = 0;
                         }
                         completion:^(BOOL finished){
                             [UIView animateWithDuration:1
                                                   delay:5
                                                 options:UIViewAnimationOptionCurveEaseInOut
                                              animations:^{
                                                  self.imageView.layer.opacity = 1;
                                              }
                                              completion:nil                          ];
                         }
         ];
    }
    

    问题中的1、2、3、4、1、2、3、4动画序列一起可以实现。

    【讨论】:

      【解决方案3】:

      这是一个老问题,但几乎没有什么变化,它出现在我的搜索中,所以这里有一个我认为更好的建议。不需要NSTimers,使用UIView上的关键帧动画方法可以达到同样的效果。

      斯威夫特 5

      // durations in seconds [ pause 5s | fade out 1s | pause 5s | fade in 1s] = 12s total
      let fadeDuration: Double = 1
      let delayDuration: Double = 5
      let totalDuration: Double = delayDuration + fadeDuration + delayDuration + fadeDuration
      
      // convert to relative times for key frames
      let fadeRelativeDuration: Double = fadeDuration / totalDuration
      let firstStartRelativeTime: Double = delayDuration / totalDuration
      let secondStartRelativeTime: Double = (delayDuration + fadeDuration + delayDuration) / totalDuration
      
      UIView.animateKeyframes(withDuration: totalDuration, delay: 0, options: [.repeat], animations: {
          UIView.addKeyframe(withRelativeStartTime: firstStartRelativeTime, relativeDuration: fadeRelativeDuration) {
              self.imageView.layer.opacity = 0
          }
          UIView.addKeyframe(withRelativeStartTime: secondStartRelativeTime, relativeDuration: fadeRelativeDuration) {
              self.imageView.layer.opacity = 1
          }
      })
      

      在应用程序后台运行后,您仍然需要重新启动动画,例如通过在您的视图或视图控制器中观察UIApplicationWillEnterForegroundNotification

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-19
        • 1970-01-01
        • 2017-12-04
        • 2012-12-02
        • 1970-01-01
        相关资源
        最近更新 更多