8

Is there any way to fetch all UIViewControllers in iOS Swift Project. I want to get array of all the UIViewControllers and check whether particular UIViewController exists or not.I have to just find the particular UIViewController exists or not in project.

2
  • are you using UINavigationController or just presenting your UIViewControllers? Commented Jul 26, 2016 at 7:50
  • You can check if they exist by create one instance of them, but not fetch all, unless you give each of them identifier and store that somewhere as enum or array Commented Jul 26, 2016 at 7:58

2 Answers 2

8

You can do it with below code.

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate if let viewControllers = appDelegate.window?.rootViewController?.presentedViewController { // Array of all viewcontroller even after presented } else if let viewControllers = appDelegate.window?.rootViewController?.childViewControllers { // Array of all viewcontroller after push } 

Swift 4.2 ( XCode 10 )

let appDelegate = UIApplication.shared.delegate as! AppDelegate if (appDelegate.window?.rootViewController?.presentedViewController) != nil { // Array of all viewcontroller even after presented } else if (appDelegate.window?.rootViewController?.children) != nil { // Array of all viewcontroller after push } 
Sign up to request clarification or add additional context in comments.

7 Comments

Hi Hasya, First code is not useful. Second else part is useful but it's not providing me whole uiviewcontroller array. It's just providing me the view controllers which we pass through the RootViewController. Means, If my project has 50 view controllers and if I will check your code on first view then it will show only first view controller as an array. I think you understand what I want to say. I want to get whole array of UIViewController.
Hope you project structure is well. Else part will work only if you have navigation controller and push / pop view. You would not be able to get whole array until you travel on though UIViewcontrollers.
Yes thanks. Main issue is same. Ok let me search more and thanks a lot :)
Store all viewcontroller names in NSUserDefault where you set up your rootViewController, then use it any where.
Yes I did get an alternate that I created an array of UIViewControllers and appending and using accordingly.
|
7

Here is an extension I made on the basis of prev answers

Uses Generics + Extension (🔸Swift 5.1)

/** * - Returns: ViewController of a class Kind * ## Examples: * UIView.vc(vcKind: CustomViewController.self) // ref to an instance of CustomViewController */ public static func vc<T: UIViewController>(vcKind: T.Type? = nil) -> T? { guard let appDelegate = UIApplication.shared.delegate, let window = appDelegate.window else { return nil } if let vc = window?.rootViewController as? T { return vc } else if let vc = window?.rootViewController?.presentedViewController as? T { return vc } else if let vc = window?.rootViewController?.children { return vc.lazy.compactMap { $0 as? T }.first } return nil } 

6 Comments

If appDelegate.window == nil then it won't work. Also your iterates through root view controller and its presented and children view controllers. If the goal is deeper your code won't find it!
@Vyachaslav Gerchicov The comment isn't very clear. As such I am unable to help / correct the answer. Could you clarify your concern? Thanks 🙏
the problem with your answer is presentedViewController can have its own children, rootViewController may be UINavigationController with view controller array and etc. So at least this function should be recursive (or should have code which allows to avoid this recursion)
Noted. I upgraded the answer with more modern code. I doubt it fixes your case. Thanks for clarifying.
you didn't edit your answer. Maybe did you forget to save it?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.