簡體   English   中英

使用Interface Builder時查看控制器遏制

[英]View Controller Containment when using Interface Builder

我正在嘗試使用Interface Builder定義一系列容器視圖控制器(可能是我的第一個錯誤)。 在故事板中,我創建了頂視圖控制器,添加了3個容器視圖,自動將每個子視圖控制器添加到故事板。 我為每個容器視圖添加了一個插座,並且能夠通過隱藏/顯示容器視圖成功地操縱子視圖。 真的沒有太多代碼可言,它只是:

-(IBAction) button1Pushed:(id)sender
{
     containerView2.hidden = true;
     containerView1.hidden = false;
}

雖然這有效,但我需要更新每個節目的內容。 viewWillAppear(和相關函數)僅在初始創建時觸發子視圖控制器,而不是在隱藏/顯示容器時觸發。 我想我可以添加類似的東西:

    [childVC1 updateContent];
    containerView1.hidden = false;

但我希望我可以依賴viewWillAppear(以及相關的功能)。 我嘗試了一些成功有限的事情,並提出了幾個問題:

  1. 我理解Apple的編程指南中用於手動創建容器的示例:
  [self addChildViewController:content]; // 1 [self.view addSubview:self.currentClientView]; [content didMoveToParentViewController:self]; // 3 

但是在使用IB時如何應用? 在該編程指南中沒有提到IB。 IB必須調用addChildViewController,因為我可以使用[self childViewControllers]找到所有容器VC。 但由於viewWillAppear只在創建時發生,這是否意味着IB也沒有繼續添加視圖?

問題1是:通過Interface Builder添加容器視圖時,IB處理的示例代碼有多少,我需要實現多少?

  1. 作為實驗,我在父視圖的viewDidLoad中添加了此代碼:
 for ( UIViewController *vc in [self childViewControllers]) { [self.view addSubview:vc.view]; [vc didMoveToParentViewController:self]; } 

這導致每個子視圖都在屏幕的左上角一次顯示在彼此的頂部。 它不再尊重IB布局,並且不出所料,不再尊重顯示/隱藏containerView。 我可以控制它們

 vc.view.hidden = true;

但他們被轉移到某個默認位置。 我可以手動重置他們的坐標,但首先使用IB的原因之一是避免通過代碼進行屏幕定位。

問題#2是:在IB中添加容器視圖時,如何管理顯示子項,同時仍然遵循IB布局? 通過操縱容器視圖的出口? 通過操縱子視圖控制器(通過[self childViewControllers]找到)? 或者是其他東西?

在一天結束時,我想要的狀態是:

  1. 在IB中為父級和子級定義屏幕布局和位置
  2. 根據用戶選擇的按鈕隱藏/顯示孩子
  3. 每次顯示子項時都會觸發viewWillAppear,允許我更新內容

任何關於達到這個州的建議都表示贊賞,謝謝!

答案1:當您通過故事板添加子視圖控制器(在本例中稱為容器視圖)時,子項將通過segue添加。 不,它不是普通意義上的推送或呈現視圖控制器的segue,但是在“超級”視圖控制器中調用的方法是prepareForSegue。 在界面構建器中,您可以將兩個控制器之間的連接命名為普通segue,並在此實例中獲取對視圖控制器的引用。 這需要整個舞蹈的地方addChildViewController,didMoveToParent等等。

答案二:我認為解決你想要的狀態是有意義的。 我看起來你已經解決了#1和#2。 至於讓viewWillAppear再次開火,你必須讓你的父母再次通過推送和彈出一個新的VC或者展示和解雇一個VC來重新開火。 只是因為你將它設置為隱藏然后取消隱藏它不會再次觸發它(隱藏基本上告訴繪圖系統不渲染它)。

推薦的方法(來自Apple,請原諒我,我不知道鏈接)是通過updateViewContraints或layoutSubviews在視圖子類中完成所有更新。 在視圖控制器世界中,類似的方法是ViewDidLayoutSubviews。 您可以通過調用[yourViewController.view setsNeedsLayout]向您的視圖發出需要再次布局的信號。 有關needsLayout的信息,請參閱UIView上的文檔。

當您按下按鈕取消隱藏viewController時,您可能想做的事情如下:

1:在viewController上設置任何更新其內容的屬性或調用方法

2:在viewControllers視圖上調用setsNeedsLayout

3:取消隱藏它。

每次顯示子視圖時,viewWillAppear都不會觸發。 調整你的想法。

在IB中創建容器視圖和子視圖時,它會設置一個嵌入segue以鏈接到子視圖控制器。

我建議你做的是為每個子視圖控制器添加唯一的segue標識符,然后在prepareForSegue中,使用if / else if / else if語句匹配每個segue ID。 找到segue Id時,將該子視圖控制器保存在父項的屬性中:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
  if ([segue.identifier isEqualToString: @"firstChildID")
    self.firstChildVC =   (FirstChildVC *) segue.destinationViewController;
  else if ([segue.identifier isEqualToString: @"secondChildID")
    self.secondChildVC =   (SecondChildVC *) segue.destinationViewController;
  else if ([segue.identifier isEqualToString: @"thirdChildID")
    self.thirdChildVC =   (ThirdChildVC *) segue.destinationViewController;
}

然后定義一個用於與子視圖控制器通信的協議,告訴他們正在顯示它們:

@protocol ChildVCProtocol

- (void) getReadyToShowView;
//whatever other methods
@end

然后讓您的每個孩子VC符合該協議。 將代碼准備好在getReadyToShowView方法中顯示。 每次讓孩子VC可見時調用該方法。

暫無
暫無

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

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