Open bill350 opened 6 years ago
I was not able to repo this. Are you sure you are laying out the vrVideoViewController.view in the view[Will/Did]LayoutSubviews?
Try the following code where the only difference is that I had to implement self.ex.addChildViewController.
protocol VRVideoViewControllerDelegate: class {
func playerIsReady()
}
/// This controller contains a GVRRendererViewController from the GVRKit by Google
final class VRVideoViewController: ViewController, GVRRendererViewControllerDelegate {
fileprivate(set) var vrPlayer: AVPlayer?
fileprivate var vrVideoPlayerController: GVRRendererViewController?
fileprivate var vrRendererView: GVRRendererView?
weak var delegate: VRVideoViewControllerDelegate?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init() {
super.init(nibName: nil, bundle: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated);
if let url = URL(string: "[SOME_VIDEO_URL]") {
self.vrPlayer = AVPlayer(url: url)
}
self.vrPlayer?.actionAtItemEnd = .none
self.vrVideoPlayerController = GVRRendererViewController()
// Be careful here, just after the delegate is set, GVR SDK Call the method "renderer()"
// in the GVRRendererViewControllerDelegate implementation
self.vrVideoPlayerController?.delegate = self
if let vrVideoPlayerController = vrVideoPlayerController {
//self.ex.addChildViewController(vrVideoPlayerController, in: self.view)
self.addChildViewController(vrVideoPlayerController)
self.view.addSubview(vrVideoPlayerController.view)
vrVideoPlayerController.didMove(toParentViewController: self);
}
let sceneRenderer = self.vrVideoPlayerController?.rendererView.renderer as? GVRSceneRenderer
let videoRenderer = sceneRenderer?.renderList.object(at: 0) as? GVRVideoRenderer
videoRenderer?.player = self.vrPlayer
self.vrRendererView = self.vrVideoPlayerController?.view as? GVRRendererView
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.delegate?.playerIsReady()
// bill350: Layout the child view controllers view here.
vrVideoPlayerController?.view.frame = self.view.bounds
}
func shouldHideTransitionView() -> Bool {
return true
}
func renderer(for displayMode: GVRDisplayMode) -> GVRRenderer! {
let videoRenderer = GVRVideoRenderer()
videoRenderer.player = self.vrPlayer
// Monoscopic = panorama style
// TopBottom = Video splitted and duplicated in two parts, vertically
// LeftRight = Video splitted and duplicated in two parts, horizontally
videoRenderer.setSphericalMeshOfRadius(50,
latitudes: 12,
longitudes: 24,
verticalFov: 180,
horizontalFov: 360,
meshType: GVRMeshType.monoscopic)
let sceneRenderer = GVRSceneRenderer()
sceneRenderer.renderList.add(videoRenderer)
if displayMode == .embedded {
sceneRenderer.hidesReticle = true
}
videoRenderer.player?.play()
return sceneRenderer
}
}
Thanks for reply @Performador. It still doesn't work.
I share with you a screen capture with the structure of the modal :
UIViewController
displayed into a UINavigationController
(navigation bar hidden in this context), modally ;UICollectionView
) of the UIViewController
;UICollectionView
, which contains the VRVideoViewController
;Is it more clear?
Thanks.
Ah, I see.
I think the problem is that you cannot have two modal VCs at the same time and GVRRendererViewController will call presentViewController if we are in the embedded mode (like the picture you shared).
But it’s embedded into a navigation controller too, so it’s technically possible. The SDK bust be fixed with this “classic” use case.
GVRRendererViewController will call it's parent VCs presentViewController method.
You can override this method in your VRVideoViewController and call [self.navigationController presentViewController ...] to route the modal presentation to the navigation controller.
"You can override this method in your VRVideoViewController and call [self.navigationController presentViewController ...] to route the modal presentation to the navigation controller."
I'm not sure about this.
If I'm right, the isModal
method is called first :
https://github.com/googlevr/gvr-ios-sdk/blob/master/Samples/GVRKit/GVRRendererViewController.m
- (void)didTapCardboardButton {
// Toggle VR mode if we are being presented.
if ([self isModal]) {
self.rendererView.VRModeEnabled = !self.rendererView.VRModeEnabled;
} else {
...
}
That's why the view switches from this state:
to this state:
Ah, yes, thanks for the explanation.
You are right. The SDK assumes that if we are modal, we are full screen but in your case, this is not true.
Hi Google VR team,
We have some issues with displaying the
GVRPlayer
correctly on aUIViewController
which is displayed into aUINavigationController
(which is displayed in modal).Use case: the player is firstly embedded in our
UIViewController
(as it is in your sample code, the only difference is that it is embedded into aVRVideoViewController
. See source below), and we want to display/switch the video in full screen next.The final issue is that when we tap on fullscreen / cardboard, the player don't switch to fullscreen mode. We've tried to push the player in the current
UINavigationController
stack (displayed in modal mode), but the OpenGL video rendering is still broken, and lens not correctly fit the entire size of the screen.Here our code integration extract for the player configuration :
Could you please update the sample code with a modal example, similar to the root
UIViewController
which is used today? We have tested your sample with modal display and we have the same rendering issue, any idea?Thanks