簡體   English   中英

IBOutlet鏈接到嵌入式視圖控制器

[英]IBOutlet link to embedded view controller

我有一個復雜的iPad視圖,我通過擁有幾個視圖控制器來管理。 我以前(在iOS6 / XCode 4.5之前)通過在代碼中分配我的視圖控制器來實現這一點,並通過指向主視圖的鏈接將各種視圖連接到它們。

我想要做的是使用新的容器視圖將視圖控制器嵌入到storyboard文件中。 我似乎無法將嵌入式視圖控制器的IBOutlet鏈接到主控制器。

是否有可能做到這一點? 或者通過標簽或代碼中的某些內容檢索嵌入式控制器?

這個問題特別關於使用容器視圖

某些情況的另一個選擇是使用-prepareForSegue:sender:捕獲嵌入式控制器。

例如,如果我在CustomContainerViewController嵌入了UINavigationController ,我可以在故事板中命名嵌入segue embedContentStack並通過CustomContainerViewController捕獲它

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"embedContentStack"]) {
        // can't assign the view controller from an embed segue via the storyboard, so capture here
        _contentStack = (UINavigationController *)segue.destinationViewController;
    }
}

我不確定你的意思是“檢索嵌入式控制器”。 如果要使用控制器,請使用UIStoryboard方法instantiateViewControllerWithIdentifier:,使用您在IB中為控制器提供的標識符。 您還可以使用performSegueWithIdentifier:sender:方法(它還實例化視圖控制器)。 您應該查看Apple文檔中的“在應用程序中使用視圖控制器”部分。 它還引用了子視圖控制器與容器控制器同時實例化的事實。

編輯后:如果在另一個視圖控制器中嵌入容器視圖,那么嵌入視圖的控制器可以從包含控制器的self.childViewControllers引用(這將是一個數組,所以如果只有一個,你可以使用lastObject獲取它) 。

這是另一個關於它的線程: 從父iOS訪問容器視圖控制器

他們建議在prepareForSegue中保留一個引用,或者在self.childViewControllers中搜索嵌入的viewController

注意事項

在繼續使用此問題的答案之前,您可能希望反映嵌入的內容是否真的需要是視圖控制器。

例如,如果你要嵌入一個UICollectionViewController子類,你可以改為嵌入一個UICollectionView子類嗎? 或者,更好的是,您是否可以嵌入一個UIView子類來隱藏簡單ViewModel背后的UICollectionView

在我正在處理的代碼庫中,我將兩個視圖控制器嵌入到另一個視圖控制器中。 兩者都可以很容易地成為普通的視圖,然后可以更容易地綁定到故事板中,沒有這個混亂的代碼。

不幸的是,它們目前是視圖控制器,我現在無法將它們簡化為簡單視圖,因此必須這樣做。

背景

正如Playful Geek所建議的那樣,我正在使用prepare(for segue:, sender:)填充嵌入segue的方法prepare(for segue:, sender:)

我想展示我正在使用的快速,因為它看起來相當整潔......

class EditionLandingViewController: UIViewController {
    fileprivate var titlesView: SectionTitlesViewController!
    fileprivate var sectionsView: SectionsViewController!
}

//MARK:-

extension EditionLandingViewController {
    private enum SegueId: String {
        case embedTitles
        case embedSections
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        guard
            let segueRawId = segue.identifier,
            let segueId = SegueId(rawValue: segueRawId)
            else { return }

        switch segueId {
        case .embedTitles:
            self.titlesView = segue.destination as! SectionTitlesViewController

        case .embedSections:
            self.sectionsView = segue.destination as! SectionsViewController
        }
    }
}

討論

我選擇將segues命名為動作方法

使用segum標識符的enum案例意味着你已經有了編譯器和工具,所以更難以得到一個segue名稱錯誤。

在這種情況下,將segue id保留在extension范圍內的private enum中似乎是合適的,因為在其他任何地方都不需要這些segue(例如,它們不能perform )。

我正在為嵌入式視圖控制器使用隱式展開類型,因為(無論如何)如果它們丟失,則是一個邏輯錯誤。

同樣,我也很樂意強制轉換目標視圖控制器類型。 同樣,如果這些類型不相同,那將是一個邏輯錯誤。

暫無
暫無

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

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