15

Here's my config:

I have a storyboard with a ListViewController. ListViewController has a subview UIView called EmptyListView. EmptyListView is shown only when there are no items in the UITableView, otherwise it is hidden.

EmptyListView has a subview UIImageView called emptyListViewArrow which visually points towards the button to create a new entry in my UITableView. This arrow is animated infinitely in an up & down fashion.

I listen for EmptyListView to send a notification when it has finished laying out it's subviews. I do this because if not, animations that mutate constraints behave incorrectly.

- (void) layoutSubviews {
    [super layoutSubviews];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"EmptyViewDidLayoutSubviews" object:nil];
}

When ListViewController observes this notification, it begins the animation:

[UIView animateWithDuration:0.8f delay:0.0f options:(UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse) animations:^{
    self.emptyListViewArrowVerticalSpace.constant = 15.0f;
    [emptyListView layoutIfNeeded];
} completion:nil];

If I put the app in the background or push another ViewController on the stack, once I come back to the app or the ListViewController, the animation is stopped/paused. I can't get it to start again.

I've tried:

  1. Listening for application will resign/become active. When resigning, I did [self.view.layer removeAllAnimations] and then tried to start the animation again using the code above.
  2. Removing the UIImageView being animated and adding it back to the parent view, and then tried to start the animation.

I'm regretting using constraints here, but would love any insight into what could be the problem.

Thank you!

4

5 回答 5

16

我遇到了同样的问题。通过以下方式解决。

yourCoreAnimation.isRemovedOnCompletion = false

或者你有一组动画

yourGroupAnimation.isRemovedOnCompletion = false
于 2018-10-01T04:43:55.287 回答
12

我不确定你在用那个通知做什么。我已经做了很多有约束的动画,而且从来没有这样做过。我认为问题在于,当您离开视图时,约束的常量值为 15(我已经通过 viewWillDisappear 中的日志验证了这一点),因此将其设置为 15 的动画将无济于事。在一个测试应用程序中,我在 viewWillAppear 中将常量设置回它的起始值 (0),它运行良好:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.bottomCon.constant = 0;
    [self.view layoutIfNeeded];
}


-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [UIView animateWithDuration:1 delay:0.0f options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse  animations:^{
        self.bottomCon.constant = -40.0f;
        [self.view layoutIfNeeded];
    } completion:nil];
}
于 2013-09-05T04:21:30.257 回答
4

这是缺点。要克服这个问题,您必须再次调用动画方法。

你可以这样做:

在控制器中添加观察者

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeAnimation:) name:UIApplicationDidBecomeActiveNotification object:nil];

一旦您恢复应用程序,这将被调用。

添加此方法:

- (void)resumeAnimation:(NSNotification *)iRecognizer {
    // Restart Animation
}

希望这会帮助你。

于 2013-09-05T04:29:29.777 回答
4

我遇到了同样的问题。我将动画应用于 viewDidLoad 中的 imageView。

UIView.animate(withDuration: 0.5, delay: 0, options: [.repeat, .autoreverse, ], animations: {

    self.myImageView.transform = self.transform
    self.myImageView.alpha = 0.7

  }

但是每当我推其他一些 VC 并回来时,动画都无法正常工作

什么对我有用

  1. 我不得不viewWillDisappear像这样重置动画

    myImageView.transform = .identity

    我的ImageView.alpha = 1

  2. 在viewWillAppear ALSO中写入上述动画块 ( UIView.animate()) 。

希望这可以帮助

于 2019-02-18T05:51:04.170 回答
0

当应用程序进入后台并再次返回前台时,您将面临同样的问题:

斯威夫特:

NotificationCenter.default.addObserver(self, selector: #selector(enterInForeground), name: NSNotification.Name(rawValue: NSNotification.Name.UIApplicationWillEnterForeground.rawValue), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(enterInBackground), name: NSNotification.Name(rawValue: NSNotification.Name.UIApplicationDidEnterBackground.rawValue), object: nil)

func enterInForeground() {
     self.animateTheLaserLine()
}
func enterInBackground() {
     // reset the position when app enters in background
     // I have added the animation on layout constrain you can take your 
     // component 
     self.laserTopConstrain.constant = 8
}
于 2018-06-29T18:48:46.677 回答