在 iOS 中显示锁定屏幕的最佳方式是什么?
What is the best way to present lock screen in iOS?
我想知道在 iOS(swift) 中显示锁屏的最佳方式。
ex) 如果用户按下主页按钮或接到电话,我想在用户重新进入应用程序时显示锁定屏幕。
所以,我尝试过这种方式。
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)
}
}
实际上效果很好。
但是,如果显示警报 window,则无法正常工作。
我该如何解决? (对不起我的工程师。)
在这些情况下,警报视图始终是一个问题。一个快速的解决方案可能是检查是否显示警报视图并将其关闭。我玩过以下游戏:
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)
}
抛开动画,这一切看起来仍然很糟糕,因为我怀疑如果导航控制器或选项卡栏控制器(或任何其他类型的内容视图控制器)内的视图控制器会显示警报视图,这个问题会再次显示本身。您可以使用查找顶级控制器的相同逻辑来始终在顶级控制器上显示警报视图来克服这个问题。
所以我转向另一种方式,我宁愿更改根视图控制器而不是呈现覆盖。所以我尝试了以下方法:
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
}
效果很好...直到再次显示警报视图。因此,经过一些检查后,我发现在警报视图的情况下,您的应用程序有多个 windows。警报会在当前警报上创建一个新的 window 是有道理的,但我不确定有人认为它是直观的还是以任何可能的方式呈现警报视图是有意义的。然后我会期待像 UIApplication.shared.showAlert(alert)
这样的东西,但让我们把这种愚蠢放在一边。
我在这里看到的唯一真正的解决方案是为您的对话框添加一个新的 window。为此,您可以环顾网络。以下内容似乎对我有用:
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()
}
只是为了填补空白。我用作覆盖视图控制器的东西:
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)
}
}
我想知道在 iOS(swift) 中显示锁屏的最佳方式。
ex) 如果用户按下主页按钮或接到电话,我想在用户重新进入应用程序时显示锁定屏幕。
所以,我尝试过这种方式。
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)
}
}
实际上效果很好。
但是,如果显示警报 window,则无法正常工作。
我该如何解决? (对不起我的工程师。)
在这些情况下,警报视图始终是一个问题。一个快速的解决方案可能是检查是否显示警报视图并将其关闭。我玩过以下游戏:
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)
}
抛开动画,这一切看起来仍然很糟糕,因为我怀疑如果导航控制器或选项卡栏控制器(或任何其他类型的内容视图控制器)内的视图控制器会显示警报视图,这个问题会再次显示本身。您可以使用查找顶级控制器的相同逻辑来始终在顶级控制器上显示警报视图来克服这个问题。
所以我转向另一种方式,我宁愿更改根视图控制器而不是呈现覆盖。所以我尝试了以下方法:
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
}
效果很好...直到再次显示警报视图。因此,经过一些检查后,我发现在警报视图的情况下,您的应用程序有多个 windows。警报会在当前警报上创建一个新的 window 是有道理的,但我不确定有人认为它是直观的还是以任何可能的方式呈现警报视图是有意义的。然后我会期待像 UIApplication.shared.showAlert(alert)
这样的东西,但让我们把这种愚蠢放在一边。
我在这里看到的唯一真正的解决方案是为您的对话框添加一个新的 window。为此,您可以环顾网络。以下内容似乎对我有用:
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()
}
只是为了填补空白。我用作覆盖视图控制器的东西:
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)
}
}