-3

I'd like to get the name of the current loaded ViewController as String.

I got this code which is working quite fine:

    if let window = UIApplication.shared.delegate?.window {
        var viewcontroller = window!.rootViewController
        if(viewcontroller is UINavigationController){
            viewcontroller = (viewcontroller as! UINavigationController).visibleViewController

        }
        print(String(describing: viewcontroller!))
    }

But the result doesn't looks like this:

 "MyViewController1"

it looks like this:

<myapplication.MyViewController1: 0x30141e210>

How can I just get the ViewControllers name/title? There must be some more effective method then just split the String between "." and ":".

EDIT: "vc!.nibName" will not work because I'm using the Storyboard!

EDIT 2: This is what the result should look like: "MyViewController1"

EDIT 3: print(viewcontroller?.title) is also not working. It's just returning "nil"

Any help would be very appreciated!

Jonas0000
  • 1,085
  • 1
  • 12
  • 36
  • I'd like to get the className of the current loaded "ViewController", - `the ViewController currently displayed to the user` - In my case I'm using the code you can find in my question above to get this name and this solution is working so far BUT it's not just returning the Name as String but it's returning this crazy `` String. **I want to fix this!** @rmaddy @Leo Dabus – Jonas0000 Mar 05 '18 at 18:52
  • This can be done with the answer you voted negatively that I have now deleted... `print(String(describing: type(of: viewcontroller!)))` – nikano Mar 05 '18 at 18:54
  • **NO it can not be done!** - Using @MarcGarcia's code will return the type like "TabBarController" instead of "MyViewController1"! `Just try the code on your own and it will open your minds` ... `:)` – Jonas0000 Mar 05 '18 at 18:57
  • But this code is working fine! 100% - Like I've added - Try it on your own or not! – Jonas0000 Mar 05 '18 at 18:59
  • I agree with @rmaddy. Something does not match between what you posted here and what you have. Jonas0000 if you want you can share your full code, and I will do my best to try to help you with that. – nikano Mar 05 '18 at 19:06
  • It is your code, so it is your choice. But I have to say it, using spaghetti code just because "it works" and do not want to get at the bottom of it doesn't look like the way that a good programmer should take – nikano Mar 05 '18 at 19:12

3 Answers3

0

if let titleString = viewController.navigationItem.title { print(titleString) }

-1

This function will return the name of the currentViewController:

/// Returns The Class Name Of A Given View Controller
///
/// - Parameter viewController: UIViewController
/// - Returns: String
func classNameFrom(_ viewController: UIViewController) -> String{

    let currentViewControllerName = NSStringFromClass(viewController.classForCoder).components(separatedBy: ".").last!

    print("Current View Controller = \(currentViewControllerName)")

    return currentViewControllerName

}

Which you can call in ViewDidLoad etc:

print(classNameFrom(self))

Second Approach and perhaps a more robust solution:

extension UIViewController {

/// Returns The Top Most ViewController In The Navigation Controller
///
/// - Parameter base: UIViewController
/// - Returns: UIViewController
func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

    if let navigationController = base as? UINavigationController {
        return topViewController(base: navigationController.visibleViewController)
    }
    if let tabBarController = base as? UITabBarController {
        if let selected = tabBarController.selectedViewController {
            return topViewController(base: selected)
        }
    }
    if let presentedViewController = base?.presentedViewController {
        return topViewController(base: presentedViewController)
    }
    return base
}

/// Returns The Class Name Of A Given View Controller
///
/// - Parameter viewController: UIViewController
/// - Returns: String
func classNameFrom(_ viewController: UIViewController) -> String{

    let currentViewControllerName = NSStringFromClass(viewController.classForCoder).components(separatedBy: ".").last!

    print("Current View Controller = \(currentViewControllerName)")

    return currentViewControllerName

    }
 }

Which can be called like so:

  guard let thisViewController = topViewController(base: self) else { return }
        print(classNameFrom(thisViewController))
BlackMirrorz
  • 7,217
  • 2
  • 20
  • 31
-2

It looks like nobody understood my question correctly. That's why I now use this "noob" solution:

   if let window = UIApplication.shared.delegate?.window {
        var viewcontroller = window!.rootViewController
        if(viewcontroller is UINavigationController){
            viewcontroller = (viewcontroller as! UINavigationController).visibleViewController
        }
        let viewControllerString = String(describing: viewcontroller!).split(separator: ".")[1].split(separator: ":")[0]
        print(viewControllerString)
    }

I hope that somebody can answer this question correctly, as long as we will probably have to live with this code lines!

Jonas0000
  • 1,085
  • 1
  • 12
  • 36