问题
在屏幕上(iOS 4)绘制自定义电影播放器控制器时,我使用 anAVPlayerLayer
来显示。我希望在播放器顶部合成一些叠加层(广告横幅、播放器控件等)。目前,这对以下层次结构非常有效:
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:
调用,以在适当的时间淡入和淡出广告横幅。当我这样做时,我将UIImageView
s添加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.1% 的不透明度来代替 0% 的不透明度。有效地隐藏元素而不会引起问题,并且淡入/淡出运行良好。
故障排除
为了确保我没有在所有非控件视图的顶部绘制电影,我将 移动AVPlayerLayer
到另一个视图,videoView
:
UIView(self.view)\ | UIView(视频视图) | UIImageView(广告横幅) | UIImageView(另一个广告横幅) | ... | UIView(控件视图)\ * | UIView [一些电影播放器控件] | UIView [更多电影播放器控件] *
我明确调用sendSubviewToBack:videoView
and 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
是一个对象,其中包含有关何时显示叠加层和多长时间的信息,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;
调用正在正确执行。
注意:刚刚尝试设置overlay.alpha = 0.5f;
而不是0.0f
首次添加视图时。叠加层现在正确淡入。因此,让视图 100% 不可见会发生一些奇怪的事情,这会阻止它在以后再次显示。没有崩溃,所以它不仅仅是引用释放的内存。
尝试的解决方法
我尝试将所有广告叠加层发送到后面videoView
,然后当每一个要显示时,我打电话给
[overlayImage removeFromSuperview];
[self.view insertSubview:overlayImage aboveView:videoView];
// dispatch hide animation
仍然没有显示它们,但是当我省略setHidden:YES
.