如何在 UIWebView 视频播放器中添加 OverLay View?

Posted

技术标签:

【中文标题】如何在 UIWebView 视频播放器中添加 OverLay View?【英文标题】:How to add OverLay View in UIWebView Video Player? 【发布时间】:2015-07-17 10:33:37 【问题描述】:

我想在UIWebView 的视频播放器上添加一些自定义控件。 我可以通过以下代码添加对它的任何控制:

首先我在下面添加通知,

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addOverLayView:) name:UIWindowDidBecomeVisibleNotification object:nil]; 

收到后,

-(void)addOverLayView:(NSNotification*)aNotification
    UIWindow *window = (UIWindow *)aNotification.object;

    if (window != self.view.window) 
        [window addSubview:anyCustomview];
    

但此视图将静态位于UIWebView 的视频视图之上。但我想实现像视频播放器的控件将隐藏然后我想隐藏我的自定义视图。

换句话说,我想在UIWebView 的视频播放器视图上实现自定义OverLayView

【问题讨论】:

从 window.subviews 获取视图引用并同时删除该视图。 你为什么不使用任何其他自定义视频播放器? 【参考方案1】:

似乎不可能“开箱即用”。文档指出电影播放器​​在这些情况下会发出通知:

When the movie player begins playing, is paused, or begins seeking forward or backward
When AirPlay playback starts or ends
When the scaling mode of the movie changes
When the movie enters or exits fullscreen mode
When the load state for network-based movies changes
When meta-information about the movie itself becomes available

因此无法知道控件何时隐藏/显示。

如果您只想显示一次视图,在用户打开视图后,您可以很容易地实现这一点,例如使用动画:

-(void)addOverLayView:(NSNotification*)aNotification
    UIWindow *window = (UIWindow *)aNotification.object;

    if (window != self.view.window) 
        [window addSubview:anyCustomview];

        [UIView animateWithDuration:2 //choose a fitting value here
                              delay:3 //this has to be chosen experimentally if you want it to match with the timing of when the controls hide
                            options:UIViewAnimationOptionCurveEaseOut
                         animations:^
                             anyCustomView.alpha = 0.0f; //fadeout animation, you can leave this block empty to have no animation
                        completion:^(BOOL finished) 
                             [anyCustomView removeFromSuperview];
                       ];
    

请注意,当用户放弃控件时,这不会隐藏您的视图。

如果您想在每次显示/隐藏控件时显示/隐藏您的视图,它会变得更加棘手。一种方法是禁用标准控件并重新创建它们 - 请记住,这并不容易。

【讨论】:

我不想只出现一次视图。该视图必须与 UIWebView 的 Player 上的控件同步。 好的,看来实现一整套自定义控件将是您的最佳选择。正如我之前所说,这不是一件容易的事。 是的。这不是一件容易的事:)【参考方案2】:

这是相当的技巧,但它确实有效。

//
//  ViewController.m
//

#import "ViewController.h"

@interface ViewController ()

@property UIWebView *webView;

@property UIWindow *playerWindow;
@property UIView *customView;
@property UIView *transitionView;
@property NSTimer *timer;

@end

@implementation ViewController

-(void)loadView

    self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    _webView = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self.view addSubview:_webView];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addOverLayView:) name:UIWindowDidBecomeVisibleNotification object:nil];



-(void)addOverLayView:(NSNotification*)aNotification

    UIWindow *window = (UIWindow *)aNotification.object;
    _customView = [UIView new];
    _customView.backgroundColor = [UIColor yellowColor];
    _customView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 80, [UIScreen mainScreen].bounds.size.width, 80);
    _customView.alpha = 0.0;
    if (window != self.view.window)
    
        _playerWindow = window;
        [_playerWindow addSubview:_customView];
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
    


- (void)timerMethod

    if(_transitionView)
    
        UIView *view = [_transitionView.subviews lastObject];
        view = [view.subviews lastObject];
        for(UIView *subView in view.subviews)
        
            if([subView.layer.sublayers count])
            
                CALayer *finalLayer = [subView.layer.sublayers lastObject];
                CAAnimation *animation = [finalLayer animationForKey:@"opacity"];
                if(animation)
                
                    if(finalLayer.opacity)
                    
                        [UIView animateWithDuration:animation.duration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^
                        _customView.alpha = 1.0; completion:nil];
                    
                    else
                    
                        [UIView animateWithDuration:animation.duration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^
                            _customView.alpha = 0.0; completion:nil];
                    
                 
            
        
    
    else
    
        for(id view in _playerWindow.subviews)
        
            NSString *className = [NSString stringWithFormat:@"%@", [view class]];
            if([className isEqualToString:@"UITransitionView"])
            
                _transitionView = view;
                break;
            
        

    


- (void)viewDidLoad 
    [super viewDidLoad];
    NSString *fullURL = @"http://www.youtube.com";
    NSURL *url = [NSURL URLWithString:fullURL];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [_webView loadRequest:requestObj];


@end

【讨论】:

嗨,CustomView 只出现一次。如果我关闭视频并播放另一个,则它不会显示。【参考方案3】:

您可以使用 ios-javascript 桥接器来完成此操作。

您可以在 WebView 中加载脚本,观察某些元素或其属性的变化。 并使用 Bridge 在您的 java 脚本和本机 iOS 代码之间进行通信。

您可以查看以下参考以获得更多帮助。 https://developer.apple.com/library/content/documentation/AppleApplications/Conceptual/SafariJSProgTopics/ObjCFromJavaScript.html#//apple_ref/doc/uid/30001215-BBCBFJCD

如果您足够强大,可以使用 HTML 创建此类视图,也可以在播放器上添加 HTML 叠加视图。

【讨论】:

【参考方案4】:

您可以添加从中心透明并从边框着色的图像

【讨论】:

以上是关于如何在 UIWebView 视频播放器中添加 OverLay View?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UIWebView 中同时播放两个视频

如何强制在 UIWebView 中播放的视频在 iPad 上全屏显示?

如何仅在给定帧中限制 UIWebView 中的视频播放

在 UIWebView 中播放 facebook 视频

如何从 UIWebView 嵌入式 YouTube 视频播放接收 NSNotifications

如何在 UIWebview 内的播放器中获取 MPMoviePlayerPlaybackStateDidChangeNotification?