如何从UIViewController或视图之外推送ViewController?

huangapple go评论167阅读模式
英文:

How to push ViewController from outside of UIViewController or view?

问题

我想要能够从我的应用程序中没有与视图相关的类(单例)中导航视图。这是因为数据在显示视图之后的某个时间点更改(例如由于网络调用的结果)。例如,应用程序(某个类)可能只在一秒后才知道用户是否在之前打开过应用程序,并且应该转到主视图或查看一些入门视图。


我的应用程序的起始点是UINavigationController中的UIViewController。业务逻辑与视图部分分开存放在Manager单例中,如下所示:

class ExampleManager: NSObject {
    
    static var shared: ExampleManager = ExampleManager()
    
    public override init() {
        super.init()
        
        SwiftSingletons.register(self)
    }
}

通过这种方式,我可以在它们之间进行交叉通信。现在,假设在这个ExampleManager的某个函数中(在它初始化后1秒钟后)它根据数据(隐式地)知道要导航到视图A或B。但是,我该如何从该管理器内部触发导航到其中一个视图?


我怀疑可以通过以下方式之一来实现这一点:

  • 使用Combine /通知(观察视图内部的数据)
    • 问题:这感觉像是在解决非常简单的事情。
  • ViewController内部使用静态函数,可以在外部调用
    • 问题:navigationController?.pushViewController(controller, animated: true)不可能,因为“实例成员'navigationController'不能在类型'ViewController'上使用”
  • 或者也许有一种方法,就像SwiftUI中的@ObservedObject一样,当数据更改时触发视图/ViewController进行重新计算?
英文:

I want to be able to navigate views from classes (singletons) in my app that have no connection to the views. The reason for this is that the data changes (for example as a result of networking calls) at some point after finishing displaying the views. For example the app (some class) may only know after one second if the user has opened the app before and should go to the main view, or see some onboarding view.


I have a UIViewController in a UINavigationController as the starting point of my app. The business logic is kept separate from the view part in Manager singletons that look like:

class ExampleManager: NSObject {
    
    static var shared: ExampleManager = ExampleManager()
    
    public override init() {
        super.init()
        
        SwiftSingletons.register(self)
    }
}

like this I can cross-communicate between them. Now let's say in one of the functions of this ExampleManager -1 second after its initialisation- the managers knows (implicitly by data) to navigate to view A or B. But how can I trigger a navigation to one of those views from within this manager?


I suspect this could either be done the following ways:

  • using combine / notifications (observing the data inside the ViewController)
    • problem: this feels like a workaround for something very simple..
  • using a static function inside the ViewController which can be called externally
    • problem: navigationController?.pushViewController(controller, animated: true) is not possible, since "Instance member 'navigationController' cannot be used on type 'ViewController'"
  • or maybe there is some way like @ObservedObject in SwiftUI that triggers the view / ViewController to recalculate when data changes?

答案1

得分: 1

抱歉,我没有足够的声誉来发表评论,但我强烈建议您研究协调器模式!它的工作方式与您尝试使用这些单例对象的方式相同。

您为VC提供一个“协调器”(只是一个对象),它负责在视图/VC之间导航。VC本身实际上不知道谁连接到谁,但协调器处理这一点。

https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps

更直接地回答您的问题,您将使您的对象ExampleManager 能够访问导航控制器或视图控制器,它将处理推送/弹出,但它不知道确切的视图是从哪里到哪里。 (请参见我上面提供的链接)

英文:

Sorry I don't have enough reputation to comment, but I would highly recommend you look into the coordinator pattern! It works in the same way that you're trying to use these singletons.

You give a VC a "coordinator" (just an object) and it handles navigating between views/VCs. The VCs themselves don't actually know who's connected to who, but the coordinator handles that.

https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps

To answer your question more directly, you'd give your object ExampleManager access to a navigationController or view controller, and it will handle pushing / popping, but it doesn't know exactly which view it's going to / from. (See the link I dropped above)

huangapple
  • 本文由 发表于 2023年3月4日 04:49:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定