簡體   English   中英

我如何實例化一個containerView與它的containerView的viewController?

[英]how can I instantiate a viewController with a containerView and it's containerView at the same time?

我想用以下容器實例化一個viewController:

let vc = self.storyboard?.instantiateViewController(withIdentifier: ContainerViewController") as? ContainerViewController

我還需要對containerView的引用,因此請嘗試以下操作:

let vc2 = vc.childViewControllers[0] as! ChildViewController

該應用程序崩潰,並顯示“索引0超出了空NSArray的范圍”

如何在加載containerViewController之前同時實例化containerViewController及其childViewController?

編輯

用例是當用戶未通過身份驗證時,AWS Cognito會轉到signInViewController。 此代碼在appDelegate中:

func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
    if self.containerViewController == nil {
        self.containerViewController = self.storyboard?.instantiateViewController(withIdentifier: "ContainerViewController") as? ContainerViewController
    }
    if self.childViewController == nil {
        self.childViewController = self.containerViewController!.childViewControllers[0] as! ChildViewController
    }

    DispatchQueue.main.async {
        self.window?.rootViewController?.present(self.containerViewController!, animated: true, completion: nil)
    }
    return self.childViewController!
}

我實例化容器並返回孩子的原因是,返回需要符合只有孩子才能執行的協議。 我想我可以刪除該容器,但是它具有我想要的功能。

簡短的回答:不能。 在您調用instantiateViewController() ,尚未加載視圖控制器的視圖。 您需要以某種方式將其顯示在屏幕上,然后在完成顯示后查找它的子視圖。

我們需要有關您的用例的更多信息,以便為您提供幫助。

編輯:

好的,幾件事:

如果在主線程上調用了startPasswordAuthentication()函數,則沒有理由對present()調用使用DispatchQueue.main.async

如果,另一方面,你startPasswordAuthentication()函數被調用在后台線程,調用instantiateViewController()也屬於一個內部DispatchQueue.main.async所以它的主線程上執行塊。 實際上,您可能只想將startPasswordAuthentication()函數的整個內容放入DispatchQueue.main.async塊中。

接下來,無法在調用instantiateViewController(withIdentifier:)之后加載containerViewController's子視圖控制器。 那不是它的工作原理。 您應該在當前調用的完成框中查找子視圖。

接下來,您不應該進入containerViewController's視圖層次結構。 您應該在該類中添加一些方法,這些方法可以讓您請求所要查找的視圖並使用它們。

如果您試圖編寫函數以同步返回子視圖控制器,則也不能這樣做。 您需要重寫startPasswordAuthentication()函數以獲取完成處理程序,並將子視圖控制器傳遞給完成處理程序

因此,代碼可能會像這樣重寫:

func startPasswordAuthentication(completion: @escaping (AWSCognitoIdentityPasswordAuthentication?)->void ) {
    DispatchQueue.main.async { [weak self] in
      guard strongSelf = self else {
        completion(nil)
        return
      }
      if self.containerViewController == nil {
        self.containerViewController = self.storyboard?.instantiateViewController(withIdentifier: "ContainerViewController") as? ContainerViewController
      }

      self.window?.rootViewController?.present(self.containerViewController!, animated: true, completion: {
        if strongSelf == nil {
          strongSelf.childViewController = self.containerViewController.getChildViewController()
        }
        completion(strongSelf.childViewController)
      }
    })
}

(該代碼已輸入到可怕的SO編輯器中,完全未經測試,並且不打算復制/粘貼。它可能包含需要修復的錯誤。這僅是一個粗略的指南。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM