Get top most UIViewController
presentViewController
shows a view controller. It doesn't return a view controller. If you're not using a UINavigationController
, you're probably looking for presentedViewController
and you'll need to start at the root and iterate down through the presented views.
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
}
For Swift 3+:
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
}
For iOS 13+
let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
if var topController = keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
}
How to find topmost view controller on iOS
iOS 4 introduced the rootViewController property on UIWindow:
[UIApplication sharedApplication].keyWindow.rootViewController;
You'll need to set it yourself after you create the view controller though.
How to check if the top most view controller is an ImagePickerController
You are setting ImagePickerController.self
but the class name is UIImagePickerController
You can use like this
if let imagePicker = UIApplication.shared.windows.first?.topViewController() as? UIImagePickerController {
// Do your stuf
}
Or
if topVC.isKind(of: UIImagePickerController.self) {
// ...
}
Note: By using this you can not cast the top view controller as a UIImagePickerController
. As it's designed by apple.
You can use this and access the view controller by this.
if let pickerHostClass = NSClassFromString("PUPhotoPickerHostViewController"), topVC.isKind(of: pickerHostClass) {
topVC.view.alpha = 0.5
}
Get the top ViewController in iOS Swift
Amit89 brought a way to a solution up. You have to call the .window
property of the AppDelegate.
So I changed the Swift code from the link below to work as intended to find the topmost ViewController. Make sure, that the view is already in the view hierarchy. So this method cannot be called from a .viewDidLoad
Extension to find the topmost ViewController*
extension UIApplication {
class func topViewController(base: UIViewController? = (UIApplication.sharedApplication().delegate as! AppDelegate).window?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
This code originated from GitHub user Yonat in a comment to an objectiveC equivalent. I only changed the bits of code to get it to work without the .keyWindow
property
How to get the current visible viewController from AppDelegate
Do conditional casting on the return value to safely check its type.
if let currentVC = UIApplication.topViewController() as? MyViewController {
//the type of currentVC is MyViewController inside the if statement, use it as you want to
}
Your whole function implementation is flawed, if it actually worked, it would lead to infinite recursion. Once you find out the type of your current top view controller in your if statements, you are calling the same function again with the current root controller as its input value. Your function only ever exists, if it reaches either a call from a view controller, whose class is none of the ones specified in your optional bindings.
Moreover, your whole implementation doesn't do anything at the moment. You find out the type of your root view controller, but than you upcast it by returning a value of type UIViewController
.
Get current ViewController in external method in Swift
extension UIApplication{
class func getPresentedViewController() -> UIViewController? {
var presentViewController = UIApplication.shared.keyWindow?.rootViewController
while let pVC = presentViewController?.presentedViewController
{
presentViewController = pVC
}
return presentViewController
}
}
just add this extension and call : UIApplication. getPresentedViewController()
Related Topics
Retrieve Only 5 Users At a Time :Firebase [Like Instagram]
How to Loop Through View Outlets in a Uiviewcontroller with Swift
Dismiss Keyboard with a Uitextview
Swift - Unit Testing Private Variables and Methods
Is There a Prefix Header (Or Something with This Functionality) in Swift
How to Use Generic Types to Get Object with Same Type
Is Swift Dictionary of Indexed for Performance? Even for Exotic Types (Uuid)
Arkit - Get Current Position of Arcamera in a Scene
Embedding Videos in a Tableview Cell
Swift 3 Error:Argument Labels '(_:)' Do Not Match Any Available Overloads
Swift: Setting an Optional Property of a Protocol
Aws Cognito Swift Credentials Provider "Logins Is Deprecated: Use Awsidentityprovidermanager"
Find Difference in Seconds Between Nsdates as Integer Using Swift
How to Create Dictionary That Can Hold Anything in Key? or All the Possible Type It Capable to Hold
Querying Below Autoid's in Firebase