2

I need to present a help screen that overlays an open keyboard - the help screen should dim the whole view underneath and keep just a small hole with full transparency to "highlight" that piece. The point is to provide some information about several view components while highlighting them. Without a keyboard, I could just put a view at top of the hierarchy, but in this case the UI uses a keyboard with a custom input accessory that needs to be visible.

I tried to insert a new UIWindow and put it above all the UIWindows:

class CustomTextField: UITextField {
    override var canResignFirstResponder: Bool {
        return false
    }
}

class ViewController: UIViewController {
    var textField: UITextField = CustomTextField()

    override func viewDidAppear(_ animated: Bool) {
        view.backgroundColor = .white
        super.viewDidAppear(animated)

        textField.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
        view.addSubview(textField)
        textField.backgroundColor = UIColor.gray
        textField.becomeFirstResponder()

        DispatchQueue.main.asyncAfter(wallDeadline: .now() + 1) {

            self.window.windowLevel = 100000002.0 // based on experiments with UIApplication.shared.windows this should be the top most window
            let controller = UIViewController()
            controller.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
            self.window.rootViewController = controller
            self.window.makeKeyAndVisible()
        }
    }
    let window = UIWindow(frame: UIScreen.main.bounds)
}

But there are two problems with this approach:

  1. The keyboard gets hidden as soon as the window becomes key and visible.
  2. Even when using windowLevel = 100000002.0 it seems that the keyboard is above the window (the keyboard gets animated, so while hiding, I can see that its above my window).

Any ideas how to deal with these two problems? Is it even possible?

Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
  • This may help you - [How to display UIView over keyboard in iOS](https://stackoverflow.com/questions/32391704/how-to-display-uiview-over-keyboard-in-ios) – Krunal Feb 01 '18 at 14:23
  • 1
    wow, you're right.. how didn't I find it? Thanks a lot! – Milan Nosáľ Feb 01 '18 at 14:28
  • @MilanNosáľ The 2 problems that you described are exactly the same 2 issues that I ran into. You would think that using a new window and making it key would make it show above the keyboard, but alas no. Why does the window disappear as soon as the keyboard appears on screen doesn't make much sense. Your answer below is what helped me get around these 2 these issues. Thanks!!! – Lance Samaria Dec 14 '21 at 11:42

1 Answers1

3

OK, as pointed out by @Krunal, this is kind of a duplicate of this question. The trick there is to add the overlay view to the window in which keyboard is (which happens to be the UIApplication.shared.windows.last):

class ViewController: UIViewController {
    var textField: UITextField = UITextField()

    override func viewDidAppear(_ animated: Bool) {
        view.backgroundColor = .white
        super.viewDidAppear(animated)

        textField.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
        view.addSubview(textField)
        textField.backgroundColor = UIColor.gray
        textField.becomeFirstResponder()

        DispatchQueue.main.asyncAfter(wallDeadline: .now() + 1) {
            // this does the trick
            let customView = UIView(frame: self.view.bounds)
            customView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
            customView.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
            UIApplication.shared.windows.last?.addSubview(customView)
        }
    }
}
Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
  • You can accept your own answer as well, if it is working for you. Doesn't matter duplicate or not :) – Krunal Feb 01 '18 at 14:59
  • @Krunal yeah, I know, but you can accept your question only after two days :).. but thank you very much - I shall leave you some upvotes as a thanks on some of your answers :D – Milan Nosáľ Feb 01 '18 at 15:01
  • This answer definitely works but I use the keyboard notification `UIResponder.keyboardWillChangeFrameNotification` to add the custom view. It's important to understand this has to be added **after** the keyboard has been added to hierarchy for your custom view to be able to float above the keyboard. I remove the custom view in the the keyboard notification `UIResponder.keyboardWillHideNotification`. My custom view was a class level property so I only had to call `myCustomView.removeFromSuperview()` to remove it. – Lance Samaria Dec 02 '21 at 17:28