2

MKMapView に複数の注釈を設定しています。ピンがクリックされたときにマップ注釈の吹き出しを使用する代わりに、代わりにサブビュー ( self.detailView) を画面の下部にアニメーション化し、何も選択されていないときにそれを元に戻したいと考えています。ユーザーがピンを選択してから別のピンを選択すると、ビューが画面外でアニメーション化され、すぐに画面上でアニメーション化されます (もちろん、新しく選択された注釈に対応するさまざまな情報があります)。

あまり考えずに、簡単にできると思われることを試してみました。注釈が選択されself.detailViewている場合は画面上でアニメーション化され、選択が解除されている場合はself.detailView画面外でアニメーション化されます。

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    NSLog( @"selected annotation view" );

    [UIView animateWithDuration:0.2f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                      animations:^{
                          [self.detailView setFrame:CGRectMake(0, 307, 320, 60)];       
                      }
                      completion:^(BOOL finished){                

                      }];
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
    NSLog( @"deselected annotation view" );

    [UIView animateWithDuration:0.2f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                      animations:^{
                          [self.detailView setFrame:CGRectMake(0, 367, 320, 60)];       
                      }
                      completion:^(BOOL finished){

                      }];

}

これは、ピンが選択されていないときにユーザーがピンを選択した場合、およびピンが選択されていて、ユーザーが空のスペースをクリックして選択を解除した場合に正常に機能します。もちろん、ピンが既に選択されている場合に問題が発生します。ユーザーが別のピンをクリックして立て続けに起動するdidDeselectAnnotationViewdidSelectAnnotationView、両方のアニメーションが同時に実行され、その結果、効果が適切に機能しません。 . 通常、最初のアニメーションの完了ブロックに 2 番目のアニメーションを配置して、アニメーションを連鎖させますが、それらは別々のメソッドにあるため、ここでは明らかにそれを行うことはできません。

この問題をどのように回避できるかについて、誰かアイデアはありますか? ありがとう!

4

1 に答える 1

2

あなたがやりたいことをするためのより良い方法があるかもしれませんが、私はあなたの特定の質問に最初に答えます。

オフとオンを繰り返しアニメーション化するビューを制御するパブリックメソッドをコントローラーに実装します。

- (void)showInfoView:(MyInfoClass*)theInfo;
- (void)hideInfoView;

あなたはそれが画面上に表示/表示されていることを示すフラグを設定し、それshowInfoViewをアニメーション化します-このコードをブロックで実行し、このように機能させるためにすぐに呼び出します...

dispatch_block_t showBlock = ^
{
    self.isShowing = YES;
    /* show code goes here */
};
showBlock();

アニメーションをオフにhideInfoViewして、アニメーション完了ブロックのフラグの設定を解除します。

showInfoViewそれを呼び出す前に、フラグをチェックして、まだ表示されていないことを確認します。showBlock表示されている場合は、ブロックをすぐに実行する代わりに、NSMutableArray呼び出されたの最後に追加しtoShowBlocksます。次にhideInfoView、フラグの設定を解除する前に、toShowBlocks配列が空でないかどうかを確認します。空でない場合は、次のように最初の項目を削除して呼び出します(配列をFIFOキューとして使用)...

dispatch_block_t nextShowBlock = [toShowBlocks objectAtIndex:0];
[toShowBlocks removeObjectAtIndex:0];
nextShowBlock();

次に、ピンが選択/選択解除されるときに、showメソッドとhideメソッドを呼び出すだけで、これで処理されます。これにより、少なくとも正しい道を歩むことができます。

たぶんもっと良い方法:

上記にはいくつかの問題があります。ユーザーがピンを押すと、アニメーションビューが非表示になり、多く表示される可能性があります。その結果、ユーザーが最後のアニメーションを取得する前に、アニメーションのキューが長くなります。また、ユーザーが地図をパ​​ンおよびズームしたときの注釈のように、ビューは地図の周りをたどりません。したがって、情報ビューにカスタム注釈を使用する方がよい場合があります。MKAnnotationビューは通常UIViewのビューのように動作せず、これがあらゆる種類の問題を引き起こすため、これは本当に苦痛です。ただし、MKAnnotationこの回答では、sをカスタムコールアウトとして使用する方法について説明しています:https ://stackoverflow.com/a/8649951/461492 。

于 2012-11-01T02:09:49.283 に答える