需要AVPlayerView在esc按钮按下时退出全屏

时间:2014-10-24 23:20:19

标签: macos cocoa video swift avfoundation

我是swift的新手,而Cocoa来自JavaFX背景。我在Xcode 6.1中构建了我的第一个Mac OS应用程序,它使用了AVPlayerView。我已将AVPlayerView配置为提供全屏按钮。播放视频时,按全屏图标会使播放器全屏显示。我正在寻找一种方法来使转义按钮使AVPlayerView回到非全屏。

到目前为止,这是我的代码:

//subclassed AVPlayerView in an attempt to capture keystrokes
class VideoPlayerView: AVPlayerView, NSWindowDelegate {

    var lastPlayValue = true   //used in toggling play on space
    var ifs = false;           //variable holding "is full screen"

    //overrode this to get keystrokes
    override var acceptsFirstResponder: Bool {
        return true
    }

    //thought this would be called when full screen is entered  
    //but it isn't
    func windowDidEnterFullScreen(notification: NSNotification) {
        ifs = true
        println("Entered full screen")
        //attempting to grab keyevents while in full screen
        becomeFirstResponder()
    }

    //thought this would be called when full screen has exited
    //but it isn't
    func windowDidExitFullScreen(notification: NSNotification) {
        ifs = false;
        //attempting to grab key events after full screen exited
        becomeFirstResponder()
        println("Exited Fullscreen")

    }


    //grabs key events.  Works when not in full screen mode
    override func keyUp(theEvent: NSEvent) {

       //handle events here.

    } 
}

我的问题是这些: 1)当视频进入全屏时,VideoPlayerView似乎失去焦点。 2)我无法检测到视频已全屏显示(windowDidEnter方法未触发) 3)我无法检测到视频已全屏离开(windowDidExit方法不会触发)

另外,当我正在学习Cocoa和Swift时,请告诉我这种方法是否在正确的轨道上。

感谢任何帮助或指示。

由于

新信息:   我已经注册了任何视图进入全屏并且从未收到任何视图的通知。仔细检查AVPlayerView,因为它“全屏”,它似乎可能模仿全屏的特征,而不是实际上是“全屏”。

2 个答案:

答案 0 :(得分:2)

我也经历过AVPlayerView的这个问题。如果我按下这样启用全屏按钮:

self.playerView.showsFullScreenToggleButton = YES;

然后我点击全屏按钮,视频进入全屏,然而,该应用程序不接受任何键输入,你不能激活Mission Montrol,LaunchPad等。这是一个非常糟糕的用户体验,我相信如果您将这样的应用程序提交到Mac App Store,它将被拒绝。此外,我还试图让我的AVPlayerView成为第一个响应者但却无济于事。

解决方案

所以,我看了一下QuickTime Player如何在全屏播放视频方面工作。而且我注意到播放器控件上没有全屏按钮。它处理全屏的方式是当用户点击窗口的全屏控件时,它会重新调整大小,如果我是正确的AVPlayerView或Apple正在使用的。要实现与此类似的功能,请执行以下操作:

//The window that contains your AVPlayerView set the delegate
 [self.window setDelegate:self];


//So you can respond to these notifications

- (void)windowDidEnterFullScreen:(NSNotification *)notification{
        // wait a bit
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                if (self.playerView.isReadyForDisplay == YES) {

        //Make sure the playerView is ready for display

        //Set the playerView to the screen's current frame (Very Important!)
         [self.playerView setFrame:[[NSScreen mainScreen] frame]];

        //Do other UI related things here e.g hide elements e.t.c

        }

        });
        }

- (void)windowWillExitFullScreen:(NSNotification *)notification{
//Do other UI related things here e.g show elements e.t.c

}

//If you have a ToolBar in your application do this:

- (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
{
    return (NSApplicationPresentationFullScreen |
            NSApplicationPresentationHideDock |
            NSApplicationPresentationAutoHideMenuBar |
            NSApplicationPresentationAutoHideToolbar);
}

// To determine if the window is in fullscreen e.g. if the application opened/restored in a fullscreen state the windowDidEnterFullScreen will not be called. So you need to do this:

- (BOOL) isFullScreenMode {
    NSApplicationPresentationOptions opts = [[NSApplication sharedApplication ] presentationOptions];
    if ( opts & NSApplicationPresentationFullScreen) {
        return YES;
    }
    return NO;
}

结论

我希望这能回答你的问题。此外,我认为这是Apple的一个错误,所以我明天会提交错误报告。

答案 1 :(得分:1)

解决方法是不允许AVPlayerView上的全屏按钮,并通过我创建的按钮手动控制全屏功能。