断断续续的全屏退出过渡
Posted
技术标签:
【中文标题】断断续续的全屏退出过渡【英文标题】:Choppy fullscreen exit transition 【发布时间】:2017-09-07 01:49:29 【问题描述】:我有一个自定义视图控制器,可以通过按钮全屏显示。它通常是视图的子视图(嵌入式)。我从嵌入进入全屏是这样的:
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()
并从全屏退出:
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
这很好,除了我在进入全屏动画中隐藏状态栏,并在退出全屏动画中显示它。这会导致我的顶视图跳回原位,而没有动画。
注意,isFullscreen
变量隐藏了状态栏。
override var prefersStatusBarHidden: Bool
return isFullscreen
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation
return .slide
这里是动画的 GIF:
Horizonal
Vertical
注意风景的顶部和底部(在风景上更容易看到)。在顶部,玩家框架会立即设置为旧位置,这会将所有内容向下移动 20 像素(或状态栏的高度)
这与隐藏状态栏有关。有人有解决办法吗?
【问题讨论】:
【参考方案1】:我想通了。这是一种 hacky 并且没有经过全面测试,但这是我想出的解决方案。
首先,获取一个变量来保存状态栏高度(不是0)。
var statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height != 0 ? UIApplication.shared.statusBarFrame.height : 20.0
然后,设置状态栏框架更改的通知。
NotificationCenter.default.addObserver(self, selector: #selector(SKPlayerViewController.updateLocalStatusBarFrameHeight), name: .UIApplicationDidChangeStatusBarFrame, object: nil)
现在,在方法中,仅当高度不为 0 时才更新变量。我们保存高度是因为状态栏可能不是 20(如果正在调用等)。
@objc private func updateLocalStatusBarFrameHeight()
let height = UIApplication.shared.statusBarFrame.height
if height > 0
self.statusBarHeight = height
现在,我更新了我的exitFullScreenToEmbed()
,仅当不是横向时才用statusBarHeight
减去计算的帧原点(因为状态栏隐藏在横向中)。
private func exitFullScreenToEmbed()
var frame = self.view.window?.convert(self.view.frame, to: self.proxyView?.superview)
self.proxyView?.superview?.addSubview(self.view)
if !(UIApplication.shared.statusBarOrientation == .landscapeRight || UIApplication.shared.statusBarOrientation == .landscapeLeft)
frame?.origin.y -= self.statusBarHeight
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
如果这对任何人有帮助,不客气。我只是在这里分享一些知识:)
【讨论】:
以上是关于断断续续的全屏退出过渡的主要内容,如果未能解决你的问题,请参考以下文章