在swift中以编程方式创建navigationController时,ViewController会出现多次

时间:2016-09-23 21:17:04

标签: ios swift uinavigationcontroller uicollectionview

我一直在以编程方式从头开始创建我的应用,而不使用Storyboard

我的应用与Firebase集成,并使用Facebook登录。

我的设置非常简单:

  
      
  1. 启动应用 - >带您到第一个名为WelcomeViewController的VC。
  2.   
  3. viewDidLoad方法中进行检查以查看用户是否已登录并存在。如果有,它会直接发送给第二个名为FilmsViewController
  4. 的VC   
  5. FilmsViewController是一个显示电影的collectionViewController。用户可以按下电影,并获取有关该电影的更多信息。
  6.   

(供参考,我已在我的应用程序中使用Facebook登录)

我有一个当前的问题,当上面的第2步发生时,它会转换为FilmsViewController,但它会像2或3次一样。所以你看到新的VC看起来像2或3次,然后内容加载。如果您按导航栏中的Back按钮,它会将您带回到它加载的2或3个viewControllers,然后再返回WelcomeViewController

我已将我的观点设置如下。

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

}

WelcomeViewController中的viewDidLoad

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 { ...
        }
}

我看了很多解决方案 - 而且没有。我只发现了一个关于这个问题的帖子,有人说解决方案是改变那个控制器的类名,我已经完成了它并没有改变任何东西。

有人可以帮我解决这个问题吗?谢谢。

2 个答案:

答案 0 :(得分:1)

addStateDidChangeListener可能被多次调用。

您应该修改它以检查是否已经推送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 { ...
    }
}

答案 1 :(得分:0)

我知道上面的解决方案有效,但是使其看起来非常简单。 这是我在项目中编写的代码。

context.Set<GSProject>().Add(entity);
await context.SaveChangesAsync();

仅在不存在控制器时将其推到导航栏。