简体   繁体   English

在iOS中呈现锁定屏幕的最佳方法是什么?

[英]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.

相关问题 在 iOS 的所有内容之上呈现视图 controller 的最佳方式是什么? - What is the best way to present a view controller on top of everything in iOS? 在iOS应用程序中呈现设置视图控制器的最佳方法是什么 - What is the best way to present settings view controller in iOS application 在iOS 6.1或7中,在屏幕顶部显示UIView的最佳方法是什么? - What is the best way to display a UIView at the top of the screen in either iOS 6.1 or 7? 呈现5个选择并仍然适合屏幕的最佳方法 - Best way to present 5 choices and still fit in the screen 布置菜单屏幕IOS的最佳方法 - Best way of Laying out menu screen IOS iOS:在iOS中,处理数据库的最佳方法是什么? - iOS: In iOS what is the best way to deal with a database? 在iOS和Android上锁定屏幕 - Lock screen on iOS and Android iOS呈现多达30个Viewcontrollers(ARC)的最佳方法 - iOS Best way to present up to 30 Viewcontrollers (ARC) 通用iOS应用初始屏幕iOS 12的最佳方法是哪一种? - Which is the best way for universal iOS app splash screen iOS 12? 在一个 UIViewController 中呈现不同模式的最佳方式是什么? - What's the best way to present different modes in one UIViewController?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM