質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

953閲覧

AVPlayerViewControllerの全画面解除でレイアウトが崩れる

komasannkomatta

総合スコア28

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/02/19 02:08

編集2019/02/19 04:45

画面の向きをDeployment InfoにてPortraitのみに設定しているアプリの画面に、AVPlayerViewControllerを配置し動作再生を行なっています。
端末を横向きにしながら、AVPlayerViewControllerの操作パネルで全画面再生し、その後全画面をやめた際に、画面が崩れます。
(端末は縦向きだが、ビュー内のデザインは横向きに配置されている感じで、画面下半分が真っ黒になります。)

縦の状態で全画面再生にした後に、端末を横向きにし全画面再生を解除した時は、正常にレイアウトされています。

端末を横向きにしながら全画面再生した後に、全画面を解除してもレイアウトが崩れない様にできないでしょうか

上記の現象は、シミュレータでは発生せず、実機でのみ発生します。
実機はiPhone8(OS:11.3.1)です。

レイアウトが崩れ状態のスクリーンショットです。
(navigationを使用し、画面遷移する様になっているViewControllerの上にAVPlayerViewControllerを配置しております)
イメージ説明

swift

1 // 生成 2 let player = AVPlayer(playerItem: playerItem) 3 playerViewController = AVPlayerViewController() 4 playerViewController.player = player 5 6 // 設定 7 playerViewController.view.frame = CGRect(x: 18, y: 165, width: 338, height: 190) 8 playerViewController.showsPlaybackControls = true // 操作パネルを非表示にする場合はfalse 9 playerViewController.videoGravity = AVLayerVideoGravity.resizeAspect.rawValue // 矩形にフィット 10 11 // 通知登録 12 NotificationCenter.default.addObserver(self, selector: #selector(didPlayerItemReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil) 13 14 // 表示 15 view.addSubview(playerViewController.view)

AVPlayerViewControllerはViewControllerのviewDidLoadで、上記コードで生成しております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/02/19 02:17

シミュレータも11.3.1でしょうか?
komasannkomatta

2019/02/19 02:26

ご回答ありがとうございます。 シミュレータは12.1でした。
fuzzball

2019/02/19 02:37

シミュレータも11.3.1で確認して下さい。
komasannkomatta

2019/02/19 03:50

シミュレータも11.3(11.3.1は見つかりませんでした)で実行したところ、レイアウト崩れが再現しました。 OSのバージョンによる障害なのでしょうか
fuzzball

2019/02/19 03:57

崩れるというのはAVPlayerViewControllerのレイアウトが崩れるってことですか? それとも、別のViewControllerからAVPlayerViewControllerを呼び出していて、呼び出し元ViewControllerのレイアウトが崩れるってことですか?
komasannkomatta

2019/02/19 04:07

ViewController全体が崩れています。 NavigationBarなども、横向き画面にレイアウトされた様な幅になっています (横向きのレイアウトを無理やり縦画面にはめた様になっています)
fuzzball

2019/02/19 04:14

AVPlayerViewControllerが別ViewControllerから呼び出されていることも書かれていないし、NavigationControllerを使ってるならそれもキチン書いて下さい。 こちらはまだスタート地点にすら立てていません。
fuzzball

2019/02/19 04:15 編集

このサイト半年以上使っててこんな質問の仕方なの?
komasannkomatta

2019/02/19 04:48

ご指摘、ありがとうございます。 必要な情報を正しく提示できず、大変申し訳ございません。 また、コードの切り出し、スクリーンショットの取得に時間がかかり大変申し訳ございません。
guest

回答2

0

調査していたらクローズしてしまいましたが、一応力技で回避出来たので載せておきます。

考え方自体はシンプルなのですが、
動画の最大化を解除したタイミングで、自分自身のビューコントローラーのframeを調整するというものです。

最大化を解除はAVPlayerViewControllerのvideoBoundsを監視し、ウィンドウのバウンズと違うときを検出すれば良さそうでした。

swift

1import UIKit 2import AVKit 3 4class ViewController: UIViewController { 5 6 let playerViewController = AVPlayerViewController() 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 // Do any additional setup after loading the view, typically from a nib. 11 title = "あああ" 12 13 let url = Bundle.main.url(forResource: "test", withExtension: "mp4")! 14 let player = AVPlayer(url: url) 15 16 playerViewController.player = player 17 addChild(playerViewController) 18 playerViewController.view.frame = CGRect(x: 0, y: 50, width: 200, height: 200) 19 playerViewController.addObserver(self, forKeyPath: "videoBounds", options: [], context: nil) 20 21 view.addSubview(playerViewController.view) 22 } 23 24 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 25 if keyPath == "videoBounds" { 26 if playerViewController.videoBounds != UIScreen.main.bounds { 27 UIView.performWithoutAnimation { 28 self.navigationController?.view.frame = UIScreen.main.bounds 29 } 30 } 31 } 32 } 33}

更に追記:

以下にもっと簡単な方法が載っていました。
AVPlayerViewController full screen rotation behavior in portrait only app
https://stackoverflow.com/questions/50977823/avplayerviewcontroller-full-screen-rotation-behavior-in-portrait-only-app/51474721#51474721

手元でもうまく動作することを確認済み:

swift:

1import UIKit 2import AVKit 3 4class ViewController: UIViewController { 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 // Do any additional setup after loading the view, typically from a nib. 9 title = "あああ" 10 11 let url = Bundle.main.url(forResource: "test", withExtension: "mp4")! 12 let player = AVPlayer(url: url) 13 let playerViewController = AVPlayerViewController() 14 playerViewController.player = player 15 addChild(playerViewController) 16 playerViewController.view.frame = CGRect(x: 0, y: 50, width: 200, height: 200) 17 view.addSubview(playerViewController.view) 18 } 19 20 override func viewWillAppear(_ animated: Bool) { 21 super.viewWillAppear(animated) 22 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } 23 appDelegate.window?.rootViewController?.view.frame = UIScreen.main.bounds 24 } 25} 26

投稿2019/02/19 05:54

編集2019/02/19 06:44
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

swift

1view.addSubview(playerViewController.view)

これがダメでしょうね。

現在のViewControllerの代わりにAVPlayerViewControllerを使うとか、AVPlayerViewControllerに遷移するとかして下さい。

Viewとして使いたいならAVPlayerViewControllerを使わない方法にして下さい。

投稿2019/02/19 05:00

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/02/19 05:10

以前にもこういうことしているコードを見たことがあるのですが、このテクニック(ViewControllerのViewだけ使う方法)はどこで覚えたのでしょうか?
komasannkomatta

2019/02/19 05:23

ご回答ありがとうございます。 常にフルスクリーンではなく、通常時は、画面中央付近に表示したい為、view.addSubview(playerViewController.view)しておりました。 https://teratail.com/questions/25941 上記を参考に、Container ViewからAVPlayerViewControllerという様に変更してみましたが、レイアウトが崩れる現象は解決しませんでした。 画面の一部に動画を表示する際に、AVPlayerViewControllerを使用するということが誤りなのでしょうか。
komasannkomatta

2019/02/19 05:25

ご指摘の通り、Container View等ではなく、完全に単一のAVPlayerViewControllerへ遷移する方法を考えてみます。
komasannkomatta

2019/02/19 05:30

fuzzball様よりのご質問を見逃しておりました。 大変申し訳ございません。 >以前にもこういうことしているコードを見たことがあるのですが、このテクニック(ViewControllerのViewだけ使う方法)はどこで覚えたのでしょうか? AVPlayerViewControllerの使用方法を調べている時に、サンプルとして見かけました。 大変申し訳ございません。場所ははっきりと覚えておりません。 どなたか個人のブログだったと思います。
komasannkomatta

2019/02/19 06:30

fuzzball様、情報ありがとうございます。 お教えいただきましたページを参考に、AVPlayerLayerで実装してみました。 任意の領域に動画を表示してみました。 AVPlayerLayerだと、全画面ボタンやシークバーなどは自分で用意しないといけないのですね。 その辺り、まだ実装できておりませんが、こちらの方法で試してみます。 長い時間、お付き合いいただき、ありがとうございました。 また、色々と情報を提示させていただく際に、不手際があり、大変申し訳ございませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問