3
void (^first_animation)();
void (^second_animation)(BOOL finished);


// First animation

first_animation = ^()
{
    g_pin_info_screen.view.alpha = 1.0;
};


// Second animation

second_animation = ^(BOOL finished)
{
    g_shadow_layer.opacity = 0.0;

    void (^set_opacity_to_1)();

    set_opacity_to_1 = ^()
    {
        g_shadow_layer.opacity = 1.0;
    };

    [UIView animateWithDuration : 2.0
            delay               : 0.0
            options             : UIViewAnimationCurveEaseInOut
            animations          : set_opacity_to_1
            completion          : nil
     ];

};



// Begin the animations

{

    float duration;

    duration = 0.35;

    [UIView animateWithDuration : duration
            delay               : 0.00
            options             : UIViewAnimationCurveEaseInOut
            animations          : first_animation
            completion          : second_animation
    ];

}

最初のアニメーションは期待どおりに実行されます。しかし、2 番目のアニメーションは完了しますが、アニメーションはありません。

上記のスキームがこれを行う適切な方法であるかどうかについて、誰かがコメントしてくれることを願っています。

4

5 に答える 5

2

サードパーティ ライブラリの助けを借りて、以下のようなソリューションがあります。

まず、便宜上、次のUIViewようにカテゴリを定義します。

+(RXPromise*) rx_animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations 
{
    RXPromise* promise = [RXPromise new];
    [UIView animateWithDuration:duration animations:animations: ^(BOOL finished){
         // ignore param finished here
         [promise fulfillWithValue:@"finished"]; // return just a string indicating success
    }];    
    return promise;
}

次に、次のように、次々に実行される任意の数の非同期アニメーションを定義します。

[UIView rx_animateWithDuration:duration animation:^{
        ... //define first animation
    }]
.then(^id(id result){
    // ignore result, it contains the fulfill value of the promise, which is @"finished"
    return [UIView rx_animateWithDuration:duration animation:^{
        ... // define second animation
    }];
}, nil)
.then(^id(id result){
    return [UIView rx_animateWithDuration:duration animation:^{
        ...  // define third animation
    }];
}, nil)
.then(^id(id result){
    return [UIView rx_animateWithDuration:duration animation:^{
        ... // and so force
    };
}, nil);

上記のステートメントは非同期です。

1 行追加のコードを使用すると、キャンセルを実現できます。

RXPromise* rootPromise = [UIView rx_animateWithDuration:duration animation:^{
        ... //define first animation
    }];

rootPromise.then(^id(id result){
    return [UIView rx_animateWithDuration:duration animation:^{
        ... // define second animation
    }];
}, nil)
.then(^id(id result){
    return [UIView rx_animateWithDuration:duration animation:^{
        ...  // define third animation
    }];
}, nil)
...

// later, in case you need to cancel pending animations:
[rootPromise cancel];

「RXPromise」ライブラリは GitHub: RXPromiseで入手できます。これらのユースケースなどのために特別に設計されています。完全な開示のため:私は著者です;)

于 2013-08-02T18:54:51.500 に答える
1

ここで確認してください: https://gist.github.com/vadimsmirnovnsk/bce345ab81a1cea25a38

機能的なスタイルでチェーンできます:

dispatch_block_t animationsBlock = ^{
    [self.view updateConstraintsIfNeeded];
    [self.view layoutIfNeeded];
};

[[[[[[[[[BARAnimation construct]
    initially:animationsBlock]
    animationWithDuration:0.425 animationConditions:^{
        [gridView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(imageView).with.offset(32.0);
        }];
    } animations:animationsBlock]
    animationWithDuration:0.425 animationConditions:^{
        [gridView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(imageView).with.offset(0.0);
        }];
    } animations:animationsBlock]
    animationWithDuration:0.425 animationConditions:^{
        [gridView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(imageView).with.offset(-32.0);
        }];
    } animations:animationsBlock]
    animationWithDuration:0.425 animationConditions:^{
        [gridView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(imageView).with.offset(0.0);
        }];
    } animations:animationsBlock]
    animationWithDuration:0.8 animationConditions:nil animations:^{
        foreView.alpha = 1.0;
    }]
    finally:^{
        [self.didEndSubject sendNext:[RACUnit defaultUnit]];
        [self.didEndSubject sendCompleted];
    }]
    run];
于 2016-03-13T13:56:02.823 に答える
0

を使用してそれらをチェーンする必要があります+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

引数内に、options:含める必要がありますUIViewAnimationOptionBeginFromCurrentState

幸運を!

于 2013-07-30T15:47:33.377 に答える