2

問題

画面上 (iOS 4) にカスタム ムービー プレーヤー コントローラーを描画するときは、 を使用しAVPlayerLayerて表示します。プレーヤーの上にいくつかのオーバーレイ (広告バナー、プレーヤー コントロールなど) を合成したいと考えています。現時点では、これは次の階層でまったく問題なく機能します。

UIView(self.view)\
                 | | UIView(コントロールビュー)\
                 * | | UIView [一部のムービー プレーヤー コントロール]
                                       | | UIView [その他のムービー プレーヤー コントロール]
                                       *

はのAVPlayerLayerサブレイヤですself.view。プレーヤーの読み込み時に、最初にレイヤーを追加してself.viewを呼び出しbringSubviewToFront:controlsView次にそのレイヤーのタップを検出し、タイマーなどでプログラムで表示/フェードアウトします。ここでは問題ありません。

広告コンテンツの動的な取得と表示をサポートするようになったので、次の階層を設定したいと思います。

UIView(self.view)\
                 | | UIImageView (広告バナー)
                 | | UIImageView (別の広告バナー)
                 | | ...
                 | | UIView(コントロールビュー)\
                 * | | UIView [一部のムービー プレーヤー コントロール]
                                       | | UIView [その他のムービー プレーヤー コントロール]
                                       *

プレーヤーの読み込み時に、適切なタイミングで広告バナーをフェード インおよびフェード アウトする呼び出しをAVPlayerインスタンスにアタッチします。addBoundaryTimeObserverForTimes:queue:usingBlock:これを行うとき、明示的な順序付けなしでサブビューとしてUIImageViewsを追加しself.viewます (したがって、他のすべての上に描画する必要があります) setHidden:YES

NSLogこれらのフェード ブロックは正しく実行され、広告バナーでそれぞれ表示と非表示を設定view.alpha = 1.0fしていますが、ビューによって表示されるものを既知の動作するローカル イメージview.alpha = 0.0fに明示的に設定しても、何も表示されません。UIImageフレーム に、さらに をに(0, 0, 320, 480)設定autoresizingMask

UIViewAutoresizingFlexibleTopMargin  |
UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin;

UIViewContentModeデフォルトです ( である必要がありますUIViewContentModeScaleToFill)。


問題に対して私が行った「解決策」

これは実際にはまったく問題に対処していませんが、0% の不透明度の代わりに 0.1% の不透明度を使用しています。問題を引き起こすことなく要素を効果的に非表示にし、フェードイン/フェードアウトがうまく機能しています。


トラブルシューティング

すべての非コントロール ビューの上にムービーを描画していないことを確認するためAVPlayerLayerに、追加のビューに移動しましたvideoView

UIView(self.view)\
                 | | UIView(ビデオビュー)
                 | | UIImageView (広告バナー)
                 | | UIImageView (別の広告バナー)
                 | | ...
                 | | UIView(コントロールビュー)\
                 * | | UIView [一部のムービー プレーヤー コントロール]
                                       | | UIView [その他のムービー プレーヤー コントロール]
                                       *

私は明示的にsendSubviewToBack:videoViewandを呼び出しますbringSubviewToFront:controlsViewが、それでも愛はありません。setHidden:YESオーバーレイ広告を最初にビュー階層に追加するときに呼び出さなければ、オーバーレイ広告を画面に表示できます。キッカーはこれです:広告も正しいタイミングで(アニメーション ブロックに応答してoverlayImage.alpha = 0.0f) 消えるので、アニメーション ブロックが問題ないことがわかります。

以下は、ムービー プレーヤーのビューに広告バナーを追加するためのコード スニペットです。

for(MyCustomAdBannerClass *overlay in overlays)
{
    UIImageView *overlayImage =
    [[UIImageView alloc] initWithImage:
     [UIImage initWithData:
      [NSData dataWithContentsOfURL:[overlay contentURL]]]];
    UIViewAutoresizing autoresizingFlags =
        UIViewAutoresizingNone;
    CGFloat x, y, width, height;
    width = [overlay width];
    height = [overlay height];
    // <snip> set x, y, autoresizing values of the above vars
    [overlayImage setFrame:CGRectMake(x, y, width, height)];
    [overlayImage setAutoresizingMask:autoresizingFlags];
    [self.view addSubview:overlayImage];
}

for(UIView *subview in self.view.subviews)
{
    if(subview == controlsView)
        [self.view bringSubviewToFront:subview];
    else if(subview == videoView)
        [self.view sendSubviewToBack:subview];
    else
        [subview setHidden:YES];
}

オーバーレイの表示/非表示のコールバックを追加するために使用するコードは次のとおりです (overlayは、オーバーレイを表示するタイミングと表示時間に関する情報を含むオブジェクトであり、実際の広告バナーが含まれています) overlayImageUIImageView

[self.player
 addBoundaryTimeObserverForTimes:[NSArray arrayWithObject:
                                  [overlay startTime]]
 queue:dispatch_get_main_queue()
 usingBlock:^{
     [UIView
      animateWithDuration:0.7
      animations:^{
          overlayImage.alpha = 1.0f;
          dispatch_time_t popTime =
          dispatch_time(DISPATCH_TIME_NOW,
                        [overlay duration] * NSEC_PER_SEC);
          dispatch_after(popTime, dispatch_get_main_queue(),
                         ^(void){
                             [UIView
                              animateWithDuration:0.7
                              animations:^{
                                  overlayImage.alpha = 0.0f;
                                  [overlayImage removeFromSuperview];
                              }];
                          }];
                }];
}];

私が言ったように、そのoverlayImage.alpha = 0.0f;呼び出しは正しく実行されています。

注:ビューが最初に追加されたときのoverlay.alpha = 0.5f;代わりに設定を試みました。0.0fオーバーレイが適切にフェードインするようになりました。そのため、ビューを 100% 非表示にして、後日再び表示されないようにするという奇妙なことが起こっています。クラッシュしないため、解放されたメモリを参照しているだけではありません。


試行された回避策

すべての広告オーバーレイを背後に送信しようとしvideoViewましたが、それぞれが表示されるときに電話をかけました

[overlayImage removeFromSuperview];
[self.view insertSubview:overlayImage aboveView:videoView];
// dispatch hide animation

まだ表示されませんが、省略しても適切にフェードしますsetHidden:YES

4

1 に答える 1

0

0.001f現在、代わりに使用し0.0fていて、表示の問題がないことに注意してください。私はまだそれがこれを行う理由を理解したいと思っています。

于 2011-06-02T08:08:14.953 に答える