强制UIView animateWithDuration完成块被调用

时间:2017-02-14 19:17:56

标签: ios objective-c uiview

我有两个重叠的动画,由于我设置我的方法的方式,导致第二个动画不会发射。我在方法的开头就有这样的支票:

- (void)animateHidden:(BOOL)hidden duration:(CGFloat)seconds delay:(CGFloat)delay options:(UIViewAnimationOptions)options disableUserInteraction:(BOOL)disableUserInteraction {
    if (self.hidden == hidden) {
        return;
    }

然后,再往下看,我的动画块看起来像这样:

__weak UIView *weakSelf = self;
[UIView animateWithDuration:seconds delay:delay options:options animations:^{
    weakSelf.alpha = hidden ? 0 : 1;
} completion:^(BOOL finished) {
    // Return user interaction to previous state
    if (disableUserInteraction) {
        weakSelf.userInteractionEnabled = userInteractionEnabled;
    }
    weakSelf.hidden = hidden;
}];

两个动画在同一个视图中启动,一个在服务调用之前,一个在之后。如果服务调用发生得足够快以至于视图仍然是动画,则永远不会调用weakSelf.hidden = hidden;,并且第二个动画将退出,因为hidden值未及时更新。

无论如何我可以强制调用animation块上的完成块吗?我需要在进行检查之前更新我的hidden属性,但无法找到实现此目的的方法。

不幸的是,拨打[self.layer removeAllAnimations]似乎无法正常工作。

3 个答案:

答案 0 :(得分:0)

您可以使用CABasicAnimation代替UIView动画,这样可以更准确地解决问题。

您可以像以下一样使用它:

CABasicAnimation* opacityZero= [CABasicAnimation animationWithKeyPath:@"opacity"];
[opacityZero setToValue:[NSNumber numberWithFloat:0.0]];
[opacityZero setDuration:duration];
[[self layer] addAnimation:opacityZero forKey:@"opacityZero"];

当您的服务电话结束时,您可以拨打[self.layer removeAllAnimations];

同样,您可以将不透明度设为1,并根据需要调整上述方法。

您可以找到更多信息here

答案 1 :(得分:0)

__block属性声明为前缀的hidden应该会有所帮助 例如,@property (nonatomic) __block BOOL hidden;

答案 2 :(得分:0)

如果您的目标是iOS 10+,请查看UIViewPropertyAnimator https://developer.apple.com/reference/uikit/uiviewpropertyanimator?language=objc

结合UIViewAnimating和UIViewImplicitlyAnimating协议,这允许动画的修改/中断/暂停/恢复/停止/等。

基本示例(IB中的按钮和视图集):

- (IBAction)startTapped:(id)sender {

    _myAnimator = [UIViewPropertyAnimator
                   runningPropertyAnimatorWithDuration:3.0
                   delay:0.0
                   options:UIViewAnimationOptionCurveLinear
                   animations:^{
                       _theRedBox.alpha = _theRedBox.alpha > 0 ? 0 : 1;
                   } completion:^(UIViewAnimatingPosition finalPosition) {
                       // do stuff
                   }];

}

- (IBAction)stopTapped:(id)sender {

    [_myAnimator stopAnimation:NO];
    [_myAnimator finishAnimationAtPosition:UIViewAnimatingPositionEnd];

}
相关问题