[英]What is the best way to present lock screen in iOS?
I wondering the best way to present lock screen in iOS(swift). 我想知道在iOS(swift)中呈现锁屏的最佳方法。
ex) If the user presses the home button or receives a call, I want to display the lock screen when user re-enter the app. 例如)如果用户按下主屏幕按钮或接听电话,我想在用户重新进入应用程序时显示锁定屏幕。
So, I tried this way. 所以,我尝试了这种方式。
func applicationWillResignActive(_ application: UIApplication) {
guard let passcodeManageView = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "passcodeManageView") as? PasscodeManageViewController else { return }
if let window = self.window, let rootViewController = window.rootViewController {
var currentController = rootViewController
while let presentController = currentController.presentedViewController {
currentController = presentController
}
currentController.present(passcodeManageView, animated: true, completion: nil)
}
}
Actually it works pretty well. 实际上,它运作良好。
However, if the alert window is displayed, it does not work normally. 但是,如果显示警报窗口,它将无法正常工作。
How can I fixed it? 我该如何解决? (Sorry for my eng.)
(对不起,我的英文。)
Alert views are always an issue in these cases. 在这些情况下,警报视图始终是一个问题。 A quick solution might be to check if alert view is presented and dismiss it.
一种快速的解决方案可能是检查是否显示警报视图并将其关闭。 I played with the following:
我玩过以下游戏:
func showOverlayController(currentController: UIViewController) {
currentController.present(OverlayViewController(), animated: true, completion: nil)
}
if let window = UIApplication.shared.keyWindow, let rootViewController = window.rootViewController {
var currentController = rootViewController
while let presentController = currentController.presentedViewController {
guard presentController as? UIAlertController == nil else {
presentController.dismiss(animated: false) {
showOverlayController(currentController: currentController)
}
return
}
currentController = presentController
}
showOverlayController(currentController: currentController)
}
Putting aside animations and all this still seems very bad because I suspect if if a view controller inside navigation controller or tab bar controller (or any other type of content view controller) would present an alert view this issue would again show itself. 放开动画,这一切似乎仍然很糟糕,因为我怀疑导航控制器或标签栏控制器(或任何其他类型的内容视图控制器)中的视图控制器是否会显示警报视图,此问题将再次显示出来。 You could use the same logic of finding a top controller to always present alert view on top controller to overcome this.
您可以使用与找到顶级控制器相同的逻辑来始终在顶级控制器上显示警报视图以克服这一问题。
So I moved to another way which is I would rather change the root view controller instead of presenting an overlay. 因此,我改用了另一种方法,即我希望更改根视图控制器而不是显示叠加层。 So I tried the following:
所以我尝试了以下方法:
static var currentOverlay: (overlay: OverlayViewController, stashedController: UIViewController)?
static func showOverlay() {
guard currentOverlay == nil else { return }
guard let currentController = UIApplication.shared.keyWindow?.rootViewController else { return }
let overlay: (overlay: OverlayViewController, stashedController: UIViewController) = (overlay: OverlayViewController(), stashedController: currentController)
self.currentOverlay = overlay
UIApplication.shared.keyWindow?.rootViewController = overlay.overlay
}
static func hideOverlay() {
guard let currentOverlay = currentOverlay else { return }
self.currentOverlay = nil
UIApplication.shared.keyWindow?.rootViewController = currentOverlay.stashedController
}
It works great... Until alert view is shown again. 效果很好...直到再次显示警报视图。 So after a bit of an inspection I found out that in case of alert views your application has multiple windows.
因此,经过一番检查,我发现在出现警报视图的情况下,您的应用程序具有多个窗口。 It makes sense an alert would create a new window over the current one but I am unsure how did anyone think it would be intuitive or that it would in any possible way make sense that you are presenting alert view.
警报会在当前窗口之上创建一个新窗口,这是有道理的,但是我不确定有人会怎么看待它是直观的,或者以任何可能的方式表明您正在显示警报视图。 I would then expect something like
UIApplication.shared.showAlert(alert)
but let's put this stupidity aside. 然后,我会期望像
UIApplication.shared.showAlert(alert)
类的东西,但让我们把这种愚蠢置于一旁。
The only real solution I see here is to add a new window for your dialog. 我在这里看到的唯一实际解决方案是为对话框添加一个新窗口。 To do that you could look around the web.
为此,您可以在网上浏览。 What seems to work for me is the following:
对于我来说似乎起作用的是以下内容:
static var currentOverlayWindow: (overlay: OverlayViewController, window: UIWindow, previousWindow: UIWindow)?
static func showOverlay() {
guard currentOverlay == nil else { return }
guard let currentWindow = UIApplication.shared.keyWindow else { return }
let overlay: (overlay: OverlayViewController, window: UIWindow, previousWindow: UIWindow) = (overlay: OverlayViewController(), window: UIWindow(frame: currentWindow.bounds), previousWindow: currentWindow)
self.currentOverlayWindow = overlay
overlay.window.backgroundColor = UIColor.black
overlay.window.rootViewController = overlay.overlay
overlay.window.windowLevel = UIWindowLevelAlert + 1
overlay.window.makeKeyAndVisible()
}
static func hideOverlay() {
guard let currentOverlayWindow = currentOverlayWindow else { return }
self.currentOverlay = nil
currentOverlayWindow.window.isHidden = true
currentOverlayWindow.previousWindow.makeKeyAndVisible()
}
Just to fill in the gaps. 只是为了填补空白。 What I used as an overlay view controller:
我用作叠加视图控制器的内容:
class OverlayViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 12.0, y: 100.0, width: 150.0, height: 55.0))
button.setTitle("Dismiss", for: .normal)
view.addSubview(button)
button.addTarget(self, action: #selector(onButton), for: .touchUpInside)
}
@objc private func onButton() {
AppDelegate.hideOverlay()
// self.dismiss(animated: true, completion: nil)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.