I have a custom view controller that can go fullscreen with a button. it normally is a subview of a view (embedded). My enter fullscreen from embed is this:
private func enterFullScreenFromEmbed() {
self.proxyView = UIView(frame: self.view.frame)
self.proxyView?.isHidden = true
self.proxyView?.autoresizingMask = self.view.autoresizingMask
self.view.superview?.addSubview(self.proxyView!)
// Now set the frame to the screen frame
let frame = self.view.window?.convert(self.view.frame, from: self.proxyView?.superview)
self.view.window?.addSubview(self.view)
self.view.frame = frame!
self.isFullscreen = true
UIView.animate(withDuration: 0.25) {
self.view.frame = self.view.window!.bounds
self.view.layoutIfNeeded()
self.setNeedsStatusBarAppearanceUpdate()
}
}
And exiting from fullscreen:
private func exitFullScreenToEmbed() {
let frame = self.view.window?.convert(self.view.frame, to: self.proxyView?.superview)
self.proxyView?.superview?.addSubview(self.view)
self.view.frame = frame!
self.isFullscreen = false
UIView.animate(withDuration: 0.25, animations: {
self.view.frame = self.proxyView!.frame
self.view.layoutIfNeeded()
self.setNeedsStatusBarAppearanceUpdate()
}) { (_) in
self.proxyView?.removeFromSuperview()
self.proxyView = nil
}
}
This works fine, except that I hide the status bar in the enter fullscreen animation, and show it in the exit fullscreen animation. This causes my top view to jump back into place, without animating.
Note, the isFullscreen variable is what hides the status bar.
override var prefersStatusBarHidden: Bool {
return isFullscreen
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
Here are gifs of the animations:
Notice the top of both and the bottom of the landscape one (easier to see on landscape). On the top, the player frame gets instantly set to the old position, and that moves everything down by 20px (or whatever the height of the status bar is)
It has something to do with the hidden status bar. Does anyone have a solution?