2013-08-23 40 views
36

是否有一種方法可以使單個ContainerView具有多個嵌入段?目標是讓ContainerView根據按下的按鈕來保存幾個不同的ViewController;一次只能看到一個。我想要使​​用嵌入段,以便在Interface Builder中故事板自動顯示爲與ContainerView相同的大小。具有多個嵌入段的ContainerView

我意識到我可以在InterfaceBuilder中手動調整其他ViewControllers的大小,但是我想要通過嵌入segue提供的自動調整大小。如果有另一種方式可用,那也可以。沒有在viewDidLoad上加載視圖是很好的 - 正如前面提到的,顯示的ViewController可以根據按下的按鈕進行更改。

+1

我知道這不是你問什麼,但作爲其他的解決方法,如何有多個ContainerViews,重疊和相同的尺寸,每個都有自己的定製SEGUE。然後,在代碼中,根據你想顯示哪個子UIViewController,使用'[self performSegueWithIdentifier:]'執行正確的segue。至少,通過這種方式,您可以保持自動調整大小,將自己的連接保持在IB中,並保留「prepareForSegue」邏輯。 –

回答

38

不,沒有辦法將多個嵌入段嵌入到一個容器視圖中。在IB中完成所有設置的一種方法是使嵌入式控制器成爲UITabBarController(隱藏標籤欄)。然後,您可以根據需要在選項卡中包含儘可能多的控制器,並使用UITabBarController的selectedIndex屬性在代碼中切換到它們。

+0

在詢問之前,我環顧四周,但我想我一直希望自己錯過了一些東西。哦,我只會接受意見是錯誤的大小。 (關於使用TabBarController的想法很有趣,但不幸的是我的ContainerView已經是另一個TabBarController了)。 –

+9

我意識到這是一個古老的答案。我解決這個問題的方式並沒有真正考慮它,而是有多個視圖容器,當時只有一個視圖容器可見。不知道這是不是最好的方法,但它工作正常。 –

+0

偉大的答案男人。仍然是一個好的解決方 – DevZarak

14

我認識到這個問題有點老,但我想回答,以防萬一你還在尋找或其他人發現這一點。我有一個類似的問題,我解決了它。

總之,你將有三個層次:
- 外部視圖控制器(「ExternalViewController」)
- 視圖控制器管理器(「ViewControllerManager」)
- 子視圖控制器你真正想成爲在(「ChildViewController」)之間切換

在帶有嵌入segue的ExternalViewController中使用容器視圖到ViewControllerManager。然後,ViewControllerManager本身會按照in this Apple documentation的描述以編程方式保存其他ChildViewController,特別是關於添加和刪除子項的部分。

添加子視圖控制器時,將其框架設置爲與ViewControllerManager的框架相同(因爲您在ViewControllerManager中執行此操作,將子框架設置爲self.view.frame)。當然,您還需要一些邏輯和外部控制來切換ExternalViewController。

希望這會有所幫助!

2

我已經通過使用-shouldPerformSegueWithIdentifier:sender:實現了。我有一個容器傳遞一個對象,並根據這個對象的類型決定顯示哪個子視圖控制器。

該結構看起來有些過於複雜,但允許基本視圖控制器忽略我擁有的不同類型的任務,並將其留給容器視圖控制器。 容器視圖控制器然後具有多個容器視圖,該容器視圖僅根據任務的類型執行。

我不知道你是否可以通過調用-performSegueWithIdentifier:sender:來手動執行嵌入段,但這也可能是一種可能性。

17

我發現這個奇妙的一篇文章,解釋究竟是如何做到這一點:http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers

你得到你的容器,並可以後面調用任何視圖控制器,有一點的成立所擁有的一切聯繫,但一旦完成,你得到一個仍然可用的故事板。

+0

這個答案是有可能根據鏈接 – Feras

+0

這對我更好。選項卡視圖控制器的主要缺點是每個選項卡的VC在不可見時繼續存在。當它們不可見時,我希望它退出,然後在需要返回時從頭開始重新初始化。 –

+0

鏈接對我不起作用 –

11

是的,我能夠通過@rdelmar post獲得靈感。你需要做的是在你的容器視圖中嵌入UITabBarViewController。然後你以編程方式選擇你想要呈現的控制器。您可能還想隱藏標籤欄。

Container view indirectly containing more views

如果你願意,你也可以隱藏在故事板文件中看到的標籤欄

您可以通過繼承的UITabBarController選擇要呈現的視圖控制器:

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.selectedIndex = 1 
} 

您可以通過在viewDidLoad()中調用self.tabBarController?.tabBar.hidden = true來隱藏視圖控制器中的選項卡欄。

+0

這很有用,但是如何從我的主VC(包含ContainerView)中選擇一個項目?我曾嘗試在'viewDidLoad()'中放置'self.tabBarController?.selectedIndex = 5',但它不起作用): – user5195185

+2

您在'prepareForSegue'方法中這樣做。就像這樣:'guard let tabBarVC = segue.destination as? UITabBarController else {return}'然後'tabBarVC.selectedIndex = 5'。也許我在打電話時犯了一些錯誤,但希望這個想法很清楚。 – Andrej

+0

謝謝,兄弟!幫助過我。 – user5195185

0

我也在這個問題上掙扎了很長時間。我曾經遇到過不同的情況,但我希望根據在視圖控制器中設置的參數來顯示類似的嵌入式表格視圖控制器。有用的是在視圖控制器中放入帶IBOutlet的嵌入式容器。容器可以在IB中設置大小約束。但是,不要在IB中嵌入任何內容。然後在viewDidLoad中,我以編程方式添加正確的視圖控制器並將其邊緣固定到嵌入容器。

這種方法的心臟被認爲是在下面的代碼(SWIFT 4):

extension UIView { 
    func pinToParent() { 
     self.translatesAutoresizingMaskIntoConstraints = false 
     let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left] 
     NSLayoutConstraint.activate(attributes.map { 
      NSLayoutConstraint(item: self, attribute: $0, relatedBy: .equal, toItem: self.superview, attribute: $0, multiplier: 1, constant: 0) 
     }) 
    } 
} 

class ColorVC: UIViewController { 

    @IBOutlet weak var tableContainer: UIView! 
    var color : rgb = .red 

    fileprivate var colorTableVC : ColorTableVC? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     switch color { 
     case .red: 
      colorTableVC = RedTableVC.init(style: .plain) 
     case .green: 
      colorTableVC = GreenTableVC.init(style: .plain) 
     case .blue: 
      colorTableVC = BlueTableVC.init(style: .plain) 
     } 
     if let vc = colorTableVC { 
      if (vc.view) != nil { 
       self.addChildViewController(vc) 
       tableContainer.addSubview(vc.view) 
       vc.view.pinToParent() 
       vc.didMove(toParentViewController: self) 
      } 
     } 
    } 
} 

在ColorVC,人們看到容器IBOutlet中和「顏色」參數由主表格視圖控制器設置。 RedTableVC,GreenTableVC和BlueTableVC都是從ColorTableVC中分類的,它是從UITableViewController中分類出來的。共同的遺產讓我使用一個「colorTableVC」變量指向任何實例化的控制器。 (並非完全必要)。但是,這避免了重複下面的代碼,以在heirarchy中添加視圖並將新控制器固定到容器視圖。在頂部,我對UIView進行了擴展以將視圖固定到其父邊。

下圖顯示瞭如何在IB中設置項目,特別是右側的視圖控制器。在這個例子中,我將「嵌入式」控制器的高度設置爲主視圖控制器高度的一半 - 所以當您旋轉設備時,可以看到IB中設置的約束確實被應用。

Embedded controller IB setup