I wish to create and present a view over each view controller in my app allowing users to interact with it or the view controllers beneath it. I want the view to always appear on top of whatever view I may present or segue to.
I have a custom UIView that appears when users tap a table view cell. Within the didSelectRowAt tableView function I have tried:
(UIApplication.shared.delegate as! AppDelegate).window?.addSubview(self.subView!)
and
self.view.addSubview(self.subView!)
Both function similarly with the view appearing over the current View controller and allowing users to interact with the table still. But when I present a new ViewController the subView disappears as it has not been added to the new View.
Subclass UIWindow
, and override addSubview()
to make sure your overlay view is always on top:
weak var overlay: MyOverlayView!
override func addSubview(_ view: UIView) {
if let overlay = view as? MyOverlayView {
self.overlay = overlay
super.addSubview(overlay)
} else {
self.insertSubview(view, belowSubview: overlay)
}
}
You must make sure the app delegate uses your custom class as the app's main window, and not the superclass UIWindow
. For this, remove the "Main storyboard file base name" entry from your Info.plist and instead instantiate the main window manually in your AppDelegate:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: MyCustomWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
self.window = MyCustomWindow(frame: UIScreen.main.bounds)
// 1. Add your overlay view to the window
// (...)
// 2. Load your initial view controller from storyboard, or
// instantiate it programmatically
// (...)
window?.makeKeyAndVisible()
return true
}
Note: I haven't tested this code. Let me know in the comments if there's a problem.