Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iOS中显示锁屏的最佳方式是什么?_Ios_Swift_Appdelegate - Fatal编程技术网

在iOS中显示锁屏的最佳方式是什么?

在iOS中显示锁屏的最佳方式是什么?,ios,swift,appdelegate,Ios,Swift,Appdelegate,我想知道在iOS(swift)中显示锁屏的最佳方式 ex)如果用户按下home(主页)按钮或接到电话,我希望在用户重新进入应用程序时显示锁定屏幕 所以,我试着这样做 func applicationWillResignActive(_ application: UIApplication) { guard let passcodeManageView = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(w

我想知道在iOS(swift)中显示锁屏的最佳方式

ex)如果用户按下home(主页)按钮或接到电话,我希望在用户重新进入应用程序时显示锁定屏幕

所以,我试着这样做

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)
    }
}
实际上它工作得很好

但是,如果显示“警报”窗口,它将无法正常工作


我怎样才能修好它?(对不起,我的英文版)

在这种情况下,警报视图总是一个问题。一个快速的解决方案可能是检查是否显示了警报视图并将其取消。我玩了以下游戏:

    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
}
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()
}
撇开动画不谈,所有这些看起来仍然很糟糕,因为我怀疑如果导航控制器或选项卡栏控制器(或任何其他类型的内容视图控制器)中的视图控制器会显示一个警报视图,那么这个问题会再次出现。您可以使用查找顶部控制器的相同逻辑来始终在顶部控制器上显示警报视图,以克服此问题

因此,我转向了另一种方式,即我宁愿更改根视图控制器,而不是显示覆盖。因此,我尝试了以下方法:

    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
}
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()
}
它工作得很好。。。直到再次显示警报视图。因此,经过一点检查,我发现在警报视图的情况下,您的应用程序有多个窗口。警报将在当前窗口的基础上创建一个新窗口是有意义的,但我不确定是否有人认为它是直观的,或者在任何可能的情况下,您显示警报视图是有意义的。然后我会期望类似于
UIApplication.shared.showAlert(alert)
的东西,但是让我们把这个愚蠢放在一边

我在这里看到的唯一真正的解决方案是为对话框添加一个新窗口。要做到这一点,你可以浏览网页。似乎对我有效的方法如下:

    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
}
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)
    }

}

谢谢你的真诚。老实说,我一点儿也不明白你的答案。因为我的技术。但是,我再次尝试你的答案。非常感谢。解决我的问题,我会选择你的答案。谢谢。@allanWay使用最后一个解决方案:)@allanWay实际上在任何地方。这可能是最好的在您的密码查看控制器。谢谢您的答复。我会再试一次。嘿@Matic Oblak,根据我在解决方案的最后一节中所说,currentOverlay要么没有定义,要么没有使用。