iOS 应用程序中的 youtube iFrame 导致全屏后半屏变黑
youtube iFrame in iOS application causes half screen to go black after full screen
我的 UIViewController
中有一个 WKWebView
,我正在将 YouTube 视频(使用 iFrame)与文本一起嵌入到 html 中。当我启动它按预期执行的视频时,它以全屏模式打开,我可以旋转横向方向,播放正常等。问题出在我关闭视频时。我的应用程序被锁定为纵向,当从视频返回时,应用程序一半是黑屏,一半是我的应用程序,一半是我的应用程序的视图看起来是横向的(对于宽度来说太大了)。
我的应用程序在整个应用程序 Info.plist
中被纵向锁定。我对视频旋转很好,它只会导致这个有趣的结果。
1. Launch WKWebView with youtube iframe
2. Click to launch video (video plays full screen)
3. Rotate device to either landscape rotations.
4. Close the player
This is where you notice that half the application is black and the other half looks to be portrait orientation in landscape layout.
当我检查之前和之后的视图时,它模仿应用程序已旋转到横向模式但设备处于纵向模式。 (视图从 414x862 开始。在观看视频并旋转并返回视图后,它显示为 862x414)
我不太确定这里发生了什么。想法?
提前致谢
我找到了 workaround/hack/solution。我将我的应用程序锁定为纵向,但覆盖了允许方向的 AppDelegate 方法。
class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return OrientationManager.allowedOrientations
}
...
}
我创建了一个 OrientationManager
,它只是一个助手 class,可以让我强制旋转并改变允许的方向。
class OrientationManager {
/// The currently allowed orientations of the application (default: .portrait)
static var allowedOrientations: UIInterfaceOrientationMask = .portrait
/**
* Method to force the current orientation of the device.
*
* - Parameter orientation: The orientation to change to.
*
* - Warning: This method uses setValue(_, forKey:) which accesses values that may change in the future
*/
static func forceOrientation(_ orientation: UIInterfaceOrientation) {
let orientationRawValue = orientation.rawValue
UIDevice.current.setValue(orientationRawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
我需要做的最后一件事是弄清楚视频何时进入和退出全屏。我发现一些通知似乎在视频进入和退出全屏时可靠地触发。发生这种情况时,我启用了视图旋转的功能,这允许它转到全屏视频后面的横向。视频关闭后,我的视图现在(不幸的是)以横向显示,然后我可以强制方向并将其重新锁定为纵向。
在 UIViewController
与 webview:
class WebViewWithVideoViewController: UIViewController {
...
// MARK: Properties
var videoDidFullScreenNotification: NSObjectProtocol?
var videoDidMinimizeNotification: NSObjectProtocol?
...
// MARK: Lifecycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.beginObserving()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.endObserving()
}
// MARK: Observers
func beginObserving() {
// This is a solution to the video causing a half black screen when the device is rotated to landscape.
// The outline of the solution is that when the video is put into full screen mode, we update the
// available orientations to include both landscape directions. Upon the video being closed,
// we force the device orientation back to portrait and then lock it back to portrait only.
// This seems to work because the UIViewController is actually in landscape once complete
// and then it animates back to the portrait orientation and seems to keep the proper ratios
// and sizes.
if self.videoDidFullScreenNotification == nil {
self.videoDidFullScreenNotification = NotificationCenter.default.addObserver(
forName: UIWindow.didBecomeVisibleNotification,
object: self.view.window,
queue: nil
) { notification in
OrientationManager.allowedOrientations = .allButUpsideDown
}
}
if self.videoDidMinimizeNotification == nil {
self.videoDidMinimizeNotification = NotificationCenter.default.addObserver(
forName: UIWindow.didBecomeHiddenNotification,
object: self.view.window,
queue: nil
) { notification in
OrientationManager.forceOrientation(.portrait)
OrientationManager.allowedOrientations = .portrait
}
}
}
func endObserving() {
if let videoDidFullScreenNotification = self.videoDidFullScreenNotification {
NotificationCenter.default.removeObserver(videoDidFullScreenNotification)
}
if let videoDidMinimizeNotification = self.videoDidMinimizeNotification {
NotificationCenter.default.removeObserver(videoDidMinimizeNotification)
}
}
...
}
这似乎已经解决了嵌入视频进出全屏后屏幕显示半黑的问题。不幸的是,当您从全屏视频中 return 时会有轻微的动画,但这是一个非常奇怪的错误的小牺牲。
希望这对解决此问题(或类似问题)的其他人有所帮助,祝您编码愉快!
我的 UIViewController
中有一个 WKWebView
,我正在将 YouTube 视频(使用 iFrame)与文本一起嵌入到 html 中。当我启动它按预期执行的视频时,它以全屏模式打开,我可以旋转横向方向,播放正常等。问题出在我关闭视频时。我的应用程序被锁定为纵向,当从视频返回时,应用程序一半是黑屏,一半是我的应用程序,一半是我的应用程序的视图看起来是横向的(对于宽度来说太大了)。
我的应用程序在整个应用程序 Info.plist
中被纵向锁定。我对视频旋转很好,它只会导致这个有趣的结果。
1. Launch WKWebView with youtube iframe
2. Click to launch video (video plays full screen)
3. Rotate device to either landscape rotations.
4. Close the player
This is where you notice that half the application is black and the other half looks to be portrait orientation in landscape layout.
当我检查之前和之后的视图时,它模仿应用程序已旋转到横向模式但设备处于纵向模式。 (视图从 414x862 开始。在观看视频并旋转并返回视图后,它显示为 862x414)
我不太确定这里发生了什么。想法?
提前致谢
我找到了 workaround/hack/solution。我将我的应用程序锁定为纵向,但覆盖了允许方向的 AppDelegate 方法。
class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return OrientationManager.allowedOrientations
}
...
}
我创建了一个 OrientationManager
,它只是一个助手 class,可以让我强制旋转并改变允许的方向。
class OrientationManager {
/// The currently allowed orientations of the application (default: .portrait)
static var allowedOrientations: UIInterfaceOrientationMask = .portrait
/**
* Method to force the current orientation of the device.
*
* - Parameter orientation: The orientation to change to.
*
* - Warning: This method uses setValue(_, forKey:) which accesses values that may change in the future
*/
static func forceOrientation(_ orientation: UIInterfaceOrientation) {
let orientationRawValue = orientation.rawValue
UIDevice.current.setValue(orientationRawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
我需要做的最后一件事是弄清楚视频何时进入和退出全屏。我发现一些通知似乎在视频进入和退出全屏时可靠地触发。发生这种情况时,我启用了视图旋转的功能,这允许它转到全屏视频后面的横向。视频关闭后,我的视图现在(不幸的是)以横向显示,然后我可以强制方向并将其重新锁定为纵向。
在 UIViewController
与 webview:
class WebViewWithVideoViewController: UIViewController {
...
// MARK: Properties
var videoDidFullScreenNotification: NSObjectProtocol?
var videoDidMinimizeNotification: NSObjectProtocol?
...
// MARK: Lifecycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.beginObserving()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.endObserving()
}
// MARK: Observers
func beginObserving() {
// This is a solution to the video causing a half black screen when the device is rotated to landscape.
// The outline of the solution is that when the video is put into full screen mode, we update the
// available orientations to include both landscape directions. Upon the video being closed,
// we force the device orientation back to portrait and then lock it back to portrait only.
// This seems to work because the UIViewController is actually in landscape once complete
// and then it animates back to the portrait orientation and seems to keep the proper ratios
// and sizes.
if self.videoDidFullScreenNotification == nil {
self.videoDidFullScreenNotification = NotificationCenter.default.addObserver(
forName: UIWindow.didBecomeVisibleNotification,
object: self.view.window,
queue: nil
) { notification in
OrientationManager.allowedOrientations = .allButUpsideDown
}
}
if self.videoDidMinimizeNotification == nil {
self.videoDidMinimizeNotification = NotificationCenter.default.addObserver(
forName: UIWindow.didBecomeHiddenNotification,
object: self.view.window,
queue: nil
) { notification in
OrientationManager.forceOrientation(.portrait)
OrientationManager.allowedOrientations = .portrait
}
}
}
func endObserving() {
if let videoDidFullScreenNotification = self.videoDidFullScreenNotification {
NotificationCenter.default.removeObserver(videoDidFullScreenNotification)
}
if let videoDidMinimizeNotification = self.videoDidMinimizeNotification {
NotificationCenter.default.removeObserver(videoDidMinimizeNotification)
}
}
...
}
这似乎已经解决了嵌入视频进出全屏后屏幕显示半黑的问题。不幸的是,当您从全屏视频中 return 时会有轻微的动画,但这是一个非常奇怪的错误的小牺牲。
希望这对解决此问题(或类似问题)的其他人有所帮助,祝您编码愉快!