当用户在iOS中导航屏幕时,如何跟踪当前可见的ViewController的变化?

发布于 2025-02-09 18:50:57 字数 413 浏览 3 评论 0原文

我正在尝试复制Firebase Analytics行为,每当ViewController屏幕与另一个更改更改时,该行为会自动启动屏幕事件。 尽管我可以使用以下方式找到当前可见的viewController:

uiapplication.shared.windows.first?.rootViewController?.presentedViewController

但我需要某种方法才能通知RootViewController的任何更改。我尝试使用KVO观察此 rootviewController ,但我没有任何回调。我发现KVO仅适用于具有动态属性的NSOBJECT。 有什么办法可以收到viewController中更改的回调?由于这将是一个库项目,因此我无法更改主代码来支持该功能。

I'm trying to replicate Firebase Analytics behaviour, which automatically fire screen events whenever ViewController screen get's changed with another.
Though I'm able to find currently visible ViewController using :

UIApplication.shared.windows.first?.rootViewController?.presentedViewController

But I need some way to get notified for any change in rootViewController. I tried to observe this rootViewController using KVO, but I don't get any callback. I found that KVO only works on NSObject with dynamic properties.
Is there any way I could receive callback for change in ViewController? Since this will be a library project, I couldn't make changes in main code to support the feature.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一抹淡然 2025-02-16 18:50:57

以下解决方案对我有用: -

import Foundation
import UIKit

public extension UIViewController {

@objc dynamic func _tracked_viewWillAppear(_ animated: Bool) {
    UserActivityTracker.startTracking(viewController: self)
}

static func swizzle() {
        //Make sure This isn't a subclass of UIViewController,
        //So that It applies to all UIViewController childs
        if self != UIViewController.self {
            return
        }
        let _: () = {
            let originalSelector =
                #selector(UIViewController.viewWillAppear(_:))
            let swizzledSelector =
                #selector(UIViewController._tracked_viewWillAppear(_:))
            let originalMethod =
                class_getInstanceMethod(self, originalSelector)
            let swizzledMethod =
                class_getInstanceMethod(self, swizzledSelector)
            method_exchangeImplementations(originalMethod!, swizzledMethod!);
        }()
    }
 } 

在上面的代码_tracked_viewwillappear()是我的自定义功能,我想在调用实际实施之前调用我的实现。
然后在AppDeliate类中,调用UiviewController.swizzle()方法,如下: -

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    UIViewController.swizzle()
    return true
}

Following solution worked for me:-

import Foundation
import UIKit

public extension UIViewController {

@objc dynamic func _tracked_viewWillAppear(_ animated: Bool) {
    UserActivityTracker.startTracking(viewController: self)
}

static func swizzle() {
        //Make sure This isn't a subclass of UIViewController,
        //So that It applies to all UIViewController childs
        if self != UIViewController.self {
            return
        }
        let _: () = {
            let originalSelector =
                #selector(UIViewController.viewWillAppear(_:))
            let swizzledSelector =
                #selector(UIViewController._tracked_viewWillAppear(_:))
            let originalMethod =
                class_getInstanceMethod(self, originalSelector)
            let swizzledMethod =
                class_getInstanceMethod(self, swizzledSelector)
            method_exchangeImplementations(originalMethod!, swizzledMethod!);
        }()
    }
 } 

In above code _tracked_viewWillAppear() is my custom function which I want to call my implementation before actual implementation called.
Then in AppDeligate class, call UIViewController.swizzle() method, as follows:-

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    UIViewController.swizzle()
    return true
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文