我有一个自定义 View Controller ,可以通过按钮进入全屏。它通常是 View 的 subview (嵌入)。我从嵌入进入全屏是这样的:
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
}
}
这很好用,除了我在进入全屏动画时隐藏了状态栏,并在退出全屏动画时显示它。这会导致我的顶 View 跳回原位,但没有动画。
请注意,isFullscreen 变量用于隐藏状态栏。
override var prefersStatusBarHidden: Bool {
return isFullscreen
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
这是动画的 gif:
注意两者的顶部和横向的底部(在横向上更容易看到)。在顶部,播放器框架立即设置为旧位置,并将所有内容向下移动 20 像素(或状态栏的任何高度)
跟隐藏状态栏有关系。有人有解决方案吗?
最佳答案
我想通了。它有点老套,没有经过全面测试,但这是我想出的解决方案。
首先获取一个变量来保存状态栏高度(不是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
}
}
如果这对任何人有帮助,不客气。我只是来分享一些知识:)
关于ios - 断断续续的全屏退出过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46086670/
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上
我想从rubyrake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调
当我将IO::popen与不存在的命令一起使用时,我在屏幕上打印了一条错误消息:irb>IO.popen"fakefake"#=>#irb>(irb):1:commandnotfound:fakefake有什么方法可以捕获此错误,以便我可以在脚本中进行检查? 最佳答案 是:升级到ruby1.9。如果您在1.9中运行它,则会引发Errno::ENOENT,您将能够拯救它。(编辑)这是在1.8中的一种hackish方式:error=IO.pipe$stderr.reopenerror[1]pipe=IO.popen'qwe'#
当我尝试使用“套接字”库中的方法“read_nonblock”时出现以下错误IO::EAGAINWaitReadable:Resourcetemporarilyunavailable-readwouldblock但是当我通过终端上的IRB尝试时它工作正常如何让它读取缓冲区? 最佳答案 IgetthefollowingerrorwhenItrytousethemethod"read_nonblock"fromthe"socket"library当缓冲区中的数据未准备好时,这是预期的行为。由于异常IO::EAGAINWaitReadab
这是一个长期存在的挫败感来源,但也许我遗漏了什么。如果我正在调试,并且我想退出调试器并返回到IRB或Rails控制台,“退出”将不起作用,因为它将退出IRB。“完成”似乎也与继续具有相同的效果。使用“删除”删除断点然后尝试“继续”或“完成”不起作用。有什么想法吗? 最佳答案 至少在byebug中,你可以这样做:evalreturn它具有计算当前函数的return语句的净效果。这有时会奏效,具体取决于调用堆栈的外观。现在虽然这不会删除当前断点....如果您只是想收回控制权,在大多数情况下这会做到这一点,具体取决于您的代码结构。在您的代
我试图制作一个可执行文件,它通过Thin作为守护进程启动Sinatra应用程序。我正在使用此代码通过Sinatra应用程序调用Thin:#!/usr/bin/envrubyrequire'thin'require'app.rb'server=::Thin::Server.new('127.0.0.1',9999,App)server.log_file='tmp/thin.log'server.pid_file='tmp/thin.pid'server.daemonize这是我执行脚本时得到的日志输出:>>WritingPIDtotmp/thin.pid>>Exiting!服务器正常启动
在Ruby脚本中,有variousways调用系统命令/命令行反引号:`commandarg1arg2`分隔形式,例如%x(commandarg1arg2)(可用其他分隔符)Kernel#system方法:system('commandarg1arg2')Kernel#exec方法:exec('commandarg1arg2')如果我希望Ruby脚本在调用的命令失败时失败(有异常)(具有非零退出代码),我可以检查特殊变量中的退出代码$?对于前两个变体:`commandarg1arg2`failunless$?==0或%x,commandarg1arg2,failunless$?==0如