最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

uikit - How can I access the name of a SwiftUI Screen inside a UIHostingController? - Stack Overflow

matteradmin5PV0评论

I have the following function to get the name of the topmost view controller in my app:

func topMostViewController() -> String {
    guard let rootVC = UIApplication.shared.connectedScenes
        pactMap({ $0 as? UIWindowScene })
        .flatMap({ $0.windows })
        .first(where: { $0.isKeyWindow })?
        .rootViewController else {
        return "Unknown Screen"
    }

    var topVC: UIViewController = rootVC

    while let presentedVC = topVC.presentedViewController {
        topVC = presentedVC
    }

    if let navigationVC = topVC as? UINavigationController, let visibleVC = navigationVC.visibleViewController {
        topVC = visibleVC
    }

    if let tabBarVC = topVC as? UITabBarController, let selectedVC = tabBarVC.selectedViewController {
        topVC = selectedVC
    }

    return String(describing: type(of: topVC))
}

My goal is to obtain the name of the currently visible Screen, whether it’s a UIViewController or a View in SwiftUI. The code works perfectly for UIViewController objects, and I can get their names as expected.

However, when dealing with SwiftUI, the name returned is always UIHostingController<ModifiedContent<AnyView, RootModifier>> . I want to access the name of the SwiftUI view inside the UIHostingController, but I’m not sure how to do this.

For example, if the visible screen is a ContentView in SwiftUI, I want to capture something like "ContentView", not "UIHostingController".

Basically, I want to do something like this:

print(type(of: self)) // ContentView

However, I need to access this information externally, outside of the SwiftUI view itself. This is for an SDK that I am working on. How can I retrieve the name of the SwiftUI view inside the UIHostingController?

I have the following function to get the name of the topmost view controller in my app:

func topMostViewController() -> String {
    guard let rootVC = UIApplication.shared.connectedScenes
        pactMap({ $0 as? UIWindowScene })
        .flatMap({ $0.windows })
        .first(where: { $0.isKeyWindow })?
        .rootViewController else {
        return "Unknown Screen"
    }

    var topVC: UIViewController = rootVC

    while let presentedVC = topVC.presentedViewController {
        topVC = presentedVC
    }

    if let navigationVC = topVC as? UINavigationController, let visibleVC = navigationVC.visibleViewController {
        topVC = visibleVC
    }

    if let tabBarVC = topVC as? UITabBarController, let selectedVC = tabBarVC.selectedViewController {
        topVC = selectedVC
    }

    return String(describing: type(of: topVC))
}

My goal is to obtain the name of the currently visible Screen, whether it’s a UIViewController or a View in SwiftUI. The code works perfectly for UIViewController objects, and I can get their names as expected.

However, when dealing with SwiftUI, the name returned is always UIHostingController<ModifiedContent<AnyView, RootModifier>> . I want to access the name of the SwiftUI view inside the UIHostingController, but I’m not sure how to do this.

For example, if the visible screen is a ContentView in SwiftUI, I want to capture something like "ContentView", not "UIHostingController".

Basically, I want to do something like this:

print(type(of: self)) // ContentView

However, I need to access this information externally, outside of the SwiftUI view itself. This is for an SDK that I am working on. How can I retrieve the name of the SwiftUI view inside the UIHostingController?

Share asked 23 hours ago Hakan OrHakan Or 675 bronze badges 2
  • This is not possible in general unless you also modify the code on the SwiftUI side. Can you accept a solution that also involves adding some identifier to your SwiftUI view? – Sweeper Commented 15 hours ago
  • If you have a solution that will cause minimum inconvenience for the person using the SDK, I would be happy to consider it. – Hakan Or Commented 14 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

Try this:

import SwiftUI

protocol DescribableViewController {
    associatedtype Content: View
}

extension DescribableViewController {
    var description: String {
        String(describing: Content.self)
    }
}

extension UIHostingController: DescribableViewController { }


func description(for viewController: UIViewController) -> String {
    if let viewController = viewController as? (any DescribableViewController) {
        viewController.description
    } else {
        String(describing: type(of: viewController)) // your code
    }
}
let viewController1 = UIHostingController(rootView: ContentView())
print(description(for: viewController1)) // prints "ContentView"
let viewController2 = UIHostingController(rootView: AnotherView())
print(description(for: viewController2)) // prints "AnotherView"
Post a comment

comment list (0)

  1. No comments so far