15

UIViewアニメーションを使用してプログラムでスクロールしているUIScrollViewサブクラスがあります。

アニメーションの実行中に、ユーザーがスクロールビューのUIImageViewコンテンツをタップまたはズームインできるようにしたいと思います。

これに似た処方を使用している間、これはうまく機能しました:

- (void) scrollSmoothlyatPixelsPerSecond:(float)thePixelsPerSecond {
    // distance in pixels / speed in pixels per second
    float animationDuration = _scrollView.contentSize.width / thePixelsPerSecond;

    [UIView beginAnimations:@"scrollAnimation" context:nil];
    [UIView setAnimationCurve: UIViewAnimationCurveLinear];
    [UIView setAnimationDuration:animationDuration];
    _scrollView.contentOffset = CGPointMake(_scrollView.contentSize.width, 0);
    [UIView commitAnimations];
}

現在、iOS 4.0以降、UIView beginAnimations:は推奨されていません。そこで、ブロックとUIView animateWithDurationを使用してコードを更新しようとしました。スクロールは、上記と同じように機能します。

重要で厄介な違いは、アニメーション中、UIScrollViewおよびその他のビューがイベント処理メソッドに応答しなくなることです。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 

また:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;

ズームしようとすると呼び出されます。

わかりやすくするために編集:タッチイベントに応答するUIViewはありません。これは、UIScrollViewだけに限定されません。UIScrollViewのピアUIToolbarは、タッチイベントに応答しません。また、UIScrollViewのピアのサブビューである他のボタンも応答しません。アニメーションの進行中は、親UIView全体がユーザーインタラクションからフリーズしているように見えます。繰り返しますが、アニメーションが完了すると、上記のすべてのUIViewが再び応答します。

これらはすべて、アニメーションの状態に関係なく、UIView beginAnimations:定式化で呼び出されます。

私のanimateWithDuration:コードは少し異なりますが、違いは重要ではありません。アニメーションが完了するとすぐに、上記のタッチイベントが再び呼び出されます...

これが私のアニメーションコードです:

- (void) scrollSmoothlyToSyncPoint:(SyncPoint *) theSyncPoint andContinue:(BOOL)theContinueFlag{

    float animationDuration = theSyncPoint.time - [player currentTime];
    [UIView animateWithDuration:animationDuration 
                          delay:0 
                        options:UIViewAnimationOptionCurveLinear 
                     animations:^{
        [_scrollView setContentOffset:theSyncPoint.contentOffset];
    } 
                     completion:^(BOOL finished){
                         if (theContinueFlag) {
                             SyncPoint *aSyncPoint = [self nextSyncPoint];
                             if (aSyncPoint) {
                                 [self scrollSmoothlyToSyncPoint:aSyncPoint andContinue:YES];
                             }
                         }
    }];
}

上記のアニメーションブロック中に発生する唯一のイベントハンドラーは次のとおりです。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

それで、質問:私は-Appleの推奨されていないラベルを無視し、beginAnimation定式化を使い続けるべきですか?hitTestを使用してズームやその他のタッチベースのイベントを再実装する必要がありますか?この問題に立ち向かうのに役立つアニメーションブロック間の実装の違いについての知識はありますか?私が行方不明になっている明らかなものはありますか?

私はAppleの新しい開発者なので、彼らの落胆したタグをどれほど真剣に受け止めるべきかわかりません。しかし、このAPIが非推奨になり、その後姿を消すのであれば、私はむしろ永続的な方向に進んでいきたいと思います。

ご清聴ありがとうございました。

4

2 に答える 2

45

次のようにアニメーションを呼び出すときは、UIViewAnimationOptionAllowUserInteractionオプションを含める必要があります。

[UIView animateWithDuration:animationDuration 
                          delay:0 
                        options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
                     <snip>];

それは卑劣なものです、私は知っています!;)

Re:「落胆した」タグ-一般に、Appleがプラットフォーム上で実行されるアプリケーションの設計に関して何もしないようにあなたに言うとき、それは通常あなた自身のためです。だから、あなたは不格好な古い方法の代わりにアニメーションブロックを採用したいと思っているのは正しいです。

于 2010-10-05T10:41:51.653 に答える
2

quickthymeの答えは正しいです。これがSwiftのスニペットです

スウィフト4

UIView.animate(
    withDuration: 0.3, // specify animation duration here 
    delay: 0, // specify delay if needed 
    options: [
        UIView.AnimationOptions.allowUserInteraction, 
        UIView.AnimationOptions.curveLinear
    ], 
    animations: {
        // animations code    
    }
)
于 2018-09-26T13:48:50.280 に答える