简体   繁体   English

快速地以编程方式创建NavigationController时,ViewController出现了多次

[英]ViewController appears mulitple times when creating a navigationController programmatically in swift

I have been creating my app completely from scratch programmatically, without using Storyboards . 我一直在以编程方式完全从零开始创建我的应用程序, 而没有使用Storyboards

My app is integrated with Firebase, and uses Facebook login. 我的应用程序已与Firebase集成,并使用Facebook登录。

My setup is fairly simple: 我的设置非常简单:

  1. Launch the app -> takes you to the first VC called WelcomeViewController . 启动应用程序->带您进入第一个称为WelcomeViewController VC。
  2. There is a check that happens in the viewDidLoad method to see if a user is already signed in and exists. viewDidLoad方法中会进行检查,以查看用户是否已经登录并存在。 If there is, it sends you straight to the second VC called FilmsViewController 如果存在,它将直接将您发送到名为FilmsViewController的第二个VC
  3. The FilmsViewController is a collectionViewController that displays films. FilmsViewController是显示影片的collectionViewController。 The user can press a film, and it takes them to more information about that film. 用户可以按下电影,然后将他们带到有关该电影的更多信息。

(For reference, I am already signed in with Facebook in my app) (供参考,我已经在我的应用程序中使用Facebook登录)

I have a current issue, where when step 2 above happens, it transitions to the FilmsViewController , but it does it like 2 or 3 times. 我有一个当前问题,当上面的第2步发生时,它会转换为FilmsViewController ,但它会执行2或3次。 So you see the new VC appear like 2 or 3 times, then the content loads. 因此,您看到新的VC出现了2或3次,然后加载了内容。 If you press the Back button in the nav bar, it takes you back through the 2 or 3 viewControllers that it loaded before taking you back to the WelcomeViewController . 如果按Back中的导航栏按钮,则可以回到通过它带你回到之前加载的2个或3 viewControllers WelcomeViewController

I have set my views up as follows. 我的观点如下。

In AppDelegate.swift : AppDelegate.swift

var window: UIWindow?
var navController: UINavigationController?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    navController = UINavigationController()
    let firstViewController: WelcomeViewController = WelcomeViewController()
    self.navController!.pushViewController(firstViewController, animated: true)

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = navController
    window?.makeKeyAndVisible()

    return true

}

In the WelcomeViewController in the viewDidLoad : viewDidLoadWelcomeViewController中:

FIRAuth.auth()?.addStateDidChangeListener { auth, user in

        if let user = user {

            // User is signed in.
            // Direct the user to the home screen

            let toFilmListVC = FilmsViewController(collectionViewLayout: UICollectionViewFlowLayout())
            self.navigationController?.pushViewController(toFilmListVC, animated: true)

        } else { ...
        }
}

I have looked loads for a solution - and nothing. 我一直在寻找解决方案的负载-没什么。 I've only found one post on this issue, where someone said the solution was to change the class name of that controller, which I have already done and it didn't change anything. 我只找到有关此问题的一篇文章,有人说解决方案是更改该控制器的类名,这已经完成,并且没有任何更改。

Can anyone help me resolve this, please? 有人可以帮我解决这个问题吗? Thank you. 谢谢。

The addStateDidChangeListener is probably being called multiple times. addStateDidChangeListener可能被多次调用。

You should modify it to check whether a FilmsViewController has already been pushed, to prevent pushing another one: 您应该对其进行修改,以检查是否已经推送了FilmsViewController ,以防止推送另一个:

FIRAuth.auth()?.addStateDidChangeListener { auth, user in

    if let user = user {

        // User is signed in.
        // Direct the user to the home screen

        // Only push one FilmsViewController onto the navigation stack!
        var shouldPush = true
        if let navigationController = self.navigationController {
            for viewController in navigationController.viewControllers {
                if viewController is FilmsViewController {
                    shouldPush = false
                }
            }
        }

        if shouldPush {
            let toFilmListVC = FilmsViewController(collectionViewLayout: UICollectionViewFlowLayout())
            self.navigationController?.pushViewController(toFilmListVC, animated: true)
        }
    } else { ...
    }
}

I know the above solutions works, but to make it look extremely simple. 我知道上述解决方案有效,但要使其看起来极其简单。 here is the code i wrote in my project. 这是我在项目中编写的代码。

let someController = SomeController.someController()
if !(self.navigationController!.viewControllers.contains(someController)){
   self.navigationController?.pushViewController(someController, animated:true)
 }

only push the controller to navigation bar if the controller is not exist. 如果控制器不存在,则仅将其推入导航栏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 以编程方式创建一个 navigationController (Swift) - Creating a navigationController programmatically (Swift) 以编程方式将NavigationController添加到指定viewController中,而无需故事板快速 - Add navigationController to specif viewController programmatically without storyboard swift Swift-TabBarController-> ViewController-> NavigationController - Swift - TabBarController -> ViewController -> NavigationController 以编程方式单击UITabBarItem时如何将ViewController推送到NavigationController? - How to push ViewController to NavigationController when UITabBarItem is clicked programmatically? 在ViewController中以编程方式使用NavigationController - Programmatically use NavigationController inside ViewController 当按下viewcontroller时,navigationController为nil - navigationController is nil,when push the viewcontroller 以编程方式呈现ViewController的嵌入NavigationController - Presenting a ViewController's embedding NavigationController programmatically 当Swift中出现嵌入式viewController时,是否有一种模糊UIViewController的方法? - Is there a way of bluring the UIViewController when the embedded viewController appears in Swift? 快速以编程方式打开viewController - Opening viewController programmatically in swift 推送ViewController时清除navigationController堆栈 - Clear navigationController stack when push ViewController
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM