5

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

  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,......

4

3 回答 3

8

我有同样的问题。我用这种方式解决了,使用 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];
于 2013-06-05T08:45:56.213 回答
1

@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动画序列一起可以实现。

于 2013-06-06T05:30:00.150 回答
1

这是一个老问题,但几乎没有什么变化,它出现在我的搜索中,所以这里有一个我认为更好的建议。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在您的视图或视图控制器中观察。

于 2019-11-23T21:47:23.333 回答