2017-04-18 132 views
0

我有一個視圖控制器(包含我的菜單)呈現在另一個視圖控制器(我的應用程序)的頂部。從所呈現的視圖控制器訪問呈現視圖控制器?

我需要從提供的視圖控制器(我的菜單)訪問呈現視圖控制器(在我的菜單下),例如訪問一些變量或使呈現視圖控制器執行其中一個segues。

但是,我只是不知道該怎麼做。 我知道「presentsViewController」和「presentedViewController」變量,但我沒有設法成功地使用它們。

任何想法?

代碼(從所呈現的VC,其作爲對AppDelegate中的參考,其中所述窗口被引用):

if let presentingViewController = 
    self.appDelegate.window?.rootViewController?.presentingViewController 
    { 
     presentingViewController.performSegue(
      withIdentifier: "nameOfMySegue", sender: self) 
    } 
+2

解決此問題的常用模式是使用委託設計模式。在你的Menu VC中聲明一個委託,並將第一個VC設置爲委託。現在你可以在代理上設置一個屬性或一個調用方法。另一種方式可能是使用通知模式。 – TheAppMentor

+1

@TheAppMentor通過直接引用呈現的視圖控制器來描述兩種更好的設計模式。然而,如果你想要一個強耦合的關係,Apple確實會提供'presentationViewController'。 – dmorrow

+0

這兩種方法實際上都有效。非常感謝。 – BUZZE

回答

4

以下是使用代理設計模式與呈現視圖控制器進行對話的方式。

首先聲明一個協議,列出委託人預期會響應的所有變量和方法。

protocol SomeProtocol { 

    var someVariable : String {get set} 

    func doSomething() 
} 

下一步:使您的演示視圖控制器符合協議。 設置您呈現VC爲代表

class MainVC: UIViewController, SomeProtocol { 

    var someVariable: String = "" 

    func doSomething() { 
     // Implementation of do 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     // Your code goes here. 

     if let destVC = segue.destination as? SubVC{ 
      destVC.delegate = self 
     } 
    } 

} 

最後,當您準備呼籲呈現VC(代表)的方法。

class SubVC: UIViewController { 
    var delegate : SomeProtocol? 


    func whenSomeEventHappens() { 

     // For eg : When a menu item is selected 

     // Set some Variable 
     delegate?.someVariable = "Some Value" 

     // Call a method on the deleate 
     delegate?.doSomething() 
    } 

} 
2

假設VCApplication正在呈現VCMenu,在VCMenu可以用訪問VCApplication:

weak let vcApplication = self.presentingViewController as? VCApplicationType 

您的示例self.appDelegate.window?.rootViewController?.presentingViewController正在尋找顯示rootViewController的ViewController - 它將是nil

編輯TheAppMentor我已經添加weak所以沒有保留週期。

+1

雖然這種方法可行,但這會導致強烈的參考週期。這是因爲,你現在有一個提交VC的菜單VC和菜單VC,並持有一個對演示VC的引用。 – TheAppMentor

+0

它的工作!非常感謝。 看來,你不能在呈現vc上執行segue,而呈現的vc尚未解除。 您必須首先解除所呈現的視圖,然後調用segue。我結束了: 自我。解除(動畫:真,完成:無) 如果讓VC = self.presentingViewController呈現爲? PresentingVCType { presentingVC.performSegue(withIdentifier:「nameOfMySegue」,sender:self) } – BUZZE

相關問題