问题
在屏幕上绘制自定义电影播放器 Controller (iOS 4) 时,我使用 AVPlayerLayer
显示。我希望在播放器顶部合成一些叠加层(广告横幅、播放器控件等)。目前,这对以下层次结构非常有效:
UIView(self.view)\ | UIView(controlsView)\ * | UIView [some movie player controls] | UIView [some more movie player controls] *
The AVPlayerLayer
is a sublayer of self.view
. On player load, I add the layer to self.view
first and call bringSubviewToFront:
on the controlsView
, and then detect taps on it and programmatically show/fadeout on a timer/whatever. No issue here.
Now that I have support for dynamically fetching and displaying advertising content, I would like to set up the following hierarchy:
UIView(self.view)\ | UIImageView (ad banner) | UIImageView (another ad banner) | ... | UIView(controlsView)\ * | UIView [some movie player controls] | UIView [some more movie player controls] *
At player load, what I then do is attach to my AVPlayer
instance some addBoundaryTimeObserverForTimes:queue:usingBlock:
calls to fade the ad banners in and out at appropriate times. As I do this, I add the UIImageView
s to self.view
as subviews with no explicit ordering (hence they should be drawn on top of everything else), and setHidden:YES
on them.
I've NSLog
'd and these fade blocks are correctly being executed, setting view.alpha = 1.0f
and view.alpha = 0.0f
for show and hide respectively on the ad banners, but nothing is appearing at all, even when explicitly setting the UIImage
displayed by the view to a known working local image and the frame to (0, 0, 320, 480)
, plus setting an autoresizingMask
of
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin;
UIViewContentMode
是默认值(应该是 UIViewContentModeScaleToFill
)。我解决问题的“解决方案”
这实际上根本没有解决这个问题,但我现在使用 0.1% 的不透明度来代替 0% 的不透明度。有效地隐藏元素而不会引起问题,并且淡入/淡出运行良好。
疑难解答
为了确保我没有在所有非控件 View 的顶部绘制电影,我移动了
AVPlayerLayer
到另一个 View ,videoView
:UIView(self.view)\ | UIView(videoView) | UIImageView (ad banner) | UIImageView (another ad banner) | ... | UIView(controlsView)\ * | UIView [some movie player controls] | UIView [some more movie player controls] *
I explicitly call sendSubviewToBack:videoView
and bringSubviewToFront:controlsView
, but still no love. I can see the overlay ads on-screen if I don't call setHidden:YES
when I first add them to the view hierarchy. The kicker is this: the ad also disappears at the correct time (in response to overlayImage.alpha = 0.0f
in my animation blocks), so I know my animation blocks are fine.
Here is a code snippet to do with adding the ad banners to my movie player's view:
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
是一个对象,其中包含有关何时显示覆盖以及显示多长时间的信息,overlayImage
是包含实际广告横幅的 UIImageView
):[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;
call 正在正确执行。注意:刚试过设置
overlay.alpha = 0.5f;
而不是 0.0f
首次添加 View 时。叠加层现在正确淡入。因此,让 View 100% 不可见会发生一些奇怪的事情,这会阻止它在以后再次显示。没有崩溃,所以它不仅仅是引用释放的内存。尝试的解决方法
我尝试在
videoView
后面发送所有广告叠加层然后当每一个要展示时,我调用[overlayImage removeFromSuperview];
[self.view insertSubview:overlayImage aboveView:videoView];
// dispatch hide animation
仍然没有显示它们,但是当我省略
setHidden:YES
时仍然会正确消失.
最佳答案
请注意,我现在使用 0.001f
而不是 0.0f
并且没有显示问题。不过,我仍然很想弄清楚它为什么会这样做。
关于ios - UIView 显示顺序问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6197741/