<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC=5] * * * * * >原文鏈接 :[Implementing a Container View Controller](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html#//apple_ref/doc/uid/TP40007457-CH11-SW1) 容器視圖控制器是將來自多個視圖控制器的內容合并到單個用戶界面中的一種方法。 容器視圖控制器通常用于方便導航,并基于現有內容創建新的用戶界面。 UIKit 中容器視圖控制器的示例包括 UINavigationController,UITabBarController 和 UISplitViewController,所有這些都可以方便用戶在不同的界面之間進行導航。 ### 設計一個自定義容器視圖控制器 大多數情況下,容器視圖控制器都像內容視圖控制器一樣管理根視圖和其他一些內容。 區別在于容器視圖控制器從其他視圖控制器獲取其內容。把獲取到的內容嵌入到自己的視圖層次結構中, 獲取的內容取決于其他視圖控制器的視圖。 容器視圖控制器負責設置嵌入視圖的大小和位置,嵌入視圖具體內容仍然被所屬視圖控制器管理。 在設計自己的容器視圖控制器時,重點關注容器和被包含的視圖控制器之間的關系。視圖控制器之間的關系可以幫助您了解它們的內容應該如何顯示在屏幕上,以及您的容器如何在內部管理它們。在設計過程中,問自己以下幾個問題: * 容器的功能是什么,它的子項有什么功能? * 同時顯示了多少個子項? * 兄弟視圖控制器之間的關系(如果有的話)是什么? * 如何從容器中添加或刪除子視圖控制器? * 子項的大小和位置會改變嗎?在什么條件下這些變化會發生? * 容器是否提供裝飾性或導航相關的視圖?(比如導航條) * 容器和它的子項之間需要什么樣的通信方式?除了 UIViewController 定義的標準的事件外,容器是否需要向它的子項傳遞特定的事件? * 容器的外觀可以以不同的方式配置嗎?如果可,怎么改變? 在定義了各個對象的功能之后,容器視圖控制器的實現相對簡單。 UIKit 的唯一要求是在容器視圖控制器和子視圖控制器之間建立一個正式的父子關系。父-子關系確保子項接收到相關的系統消息。除此之外,實際上大多數工作都是在包含在視圖的布局和管理過程中,這對于每個容器來說都是不同的。可以將視圖放置在容器的內容區域的任何位置,任意大小。還可以向視圖層次添加自定義視圖,以提供裝飾或幫助導航。 #### 示例1:UINavigationController UINavigationController 支持通過分層數據集的導航。 導航界面一次顯示一個子視圖控制器。 界面頂部的導航欄顯示數據層次結構中的當前位置,并顯示后退按鈕以向后移動一個層級。 數據層次的導航留給了子視圖控制器,涉及到列表或按鈕的使用。 視圖控制器之間的導航由導航控制器及其子節點共同管理。 當用戶與子視圖控制器 A 的按鈕或表格行交互時,子視圖控制器 A 要求導航控制器將新的視圖控制器 B 推入視圖。A 處理 B 的內容的配置,但導航控制器管理過渡動畫。 導航控制器還管理導航欄,該導航欄顯示用來關閉最上面的視圖控制器的后退按鈕。 圖 5-1 顯示了導航控制器及其視圖的結構。大多數內容區域由最上面子視圖控制器填充,只有一小部分被導航欄占據。 ###### 圖 5-1 導航界面的結構 ![](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/Art/VCPG_structure-of-navigation-interface_5-1_2x.png) 在緊湊的和常規的環境中,導航控制器一次只顯示一個子視圖控制器。導航控制器調整它的子空間以適應可用的空間。 #### 示例1:UISplitViewController UISplitViewController 對象以 **主 - 細節** 布置顯示兩個視圖控制器的內容。 在這種安排中,一個視圖控制器(主視圖)的內容決定了其他視圖控制器顯示的細節。 兩個視圖控制器的可見性是可配置的,但也受當前環境的支配。 在正常的水平環境中,UISplitViewController 可以同時顯示兩個子視圖控制器,或者可以根據需要隱藏主視圖控制器。 在緊湊的環境中,UISplitViewController 一次只顯示一個視圖控制器。 圖 5-2 顯示了在一個規則的水平環境中的 UISplitViewController 及其視圖的結構。 UISplitViewController 本身只有默認的容器視圖。 在這個例子中,兩個子視圖是并排顯示的。 子視圖的大小是可配置的,主視圖的可見性也是可配置的。 ###### 圖 5-2 UISplitViewController 界面 ![](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/Art/VCPG-split-view-inerface_5-2_2x.png) ### 在 Interface Builder 中配置容器 要在設計時創建父子容器關系,請將容器視圖對象添加到故事板場景中,如圖5-3所示。 容器視圖對象是代表子視圖控制器內容的占位符對象。 使用該視圖來調整和定位與容器中其他視圖相關的子視圖。 ###### 圖 5-3 在 Interface Builder 中添加容器視圖 ![](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/Art/container_view_embed_2x.png) 當加載一個或多個容器視圖的視圖控制器時, Interface Builder 還會加載與這些視圖關聯的子視圖控制器。必須在與父類相同的時間實例化子元素,以便創建適當的父子關系。 如果不使用 Interface Builder 來設置 容器-子容器 關系,那么您必須通過編程方式將每個子節點添加到容器視圖控制器來創建這些關系,如[ Adding a Child View Controller to Your Content ](https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html#//apple_ref/doc/uid/TP40007457-CH11-SW13)所描述的那樣。 ### 實現一個自定義容器視圖控制器 要實現容器視圖控制器,必須在視圖控制器和子視圖控制器之間建立關系。在嘗試管理視圖控制器的視圖之前,需要建立這些父子關系。這樣做可以讓 UIKit 知道你的視圖控制器是在管理子節點的大小和位置。可以在 Interface Builder 中創建這些關系,或者以編程方式創建它們。在以編程方式創建父子關系時,作為您的視圖控制器設置的一部分,需要顯式地添加和刪除子視圖控制器。 #### 添加子視圖控制器 要以編程的方式將子視圖控制器合并到容器視圖控制器中,通過以下步驟創建相關視圖控制器之間的父子關系: 1. 調用容器視圖控制器的 addChildViewController: 方法。 這個方法告訴 UIKit 你的容器視圖控制器現在正在管理子視圖控制器的視圖。 2. 將子視圖添加到容器的視圖層次結構中。 永遠記得把設置子節點根視圖的大小和位置作為這個過程的一部分。 3. 添加任約束來管理子節點根視圖的大小和位置。 4. 調用子視圖控制器的 didMoveToParentViewController: 方法。 清單 5-1 展示了一個容器視圖控制器如何在其容器中嵌入一個子視圖控制器。 建立父子關系后,容器設置其子節點的 frame,并將子視圖添加到自己的視圖層次結構中。 設置子視圖的 frame 大小很重要,能確保視圖在容器中正確顯示。 在添加視圖之后,容器視圖控制器調用子視圖控制器的 didMoveToParentViewController: 方法,以使子視圖控制器有機會對視圖所有權的更改做出響應。 ###### 清單5-1 添加子視圖控制器 ~~~ - (void) displayContentController: (UIViewController*) content { [self addChildViewController:content]; content.view.frame = [self frameForContentController]; [self.view addSubview:self.currentClientView]; [content didMoveToParentViewController:self]; } ~~~ 在前面的例子中,注意只調用了孩子的 didMoveToParentViewController: 方法。 那是因為 addChildViewController: 方法為調用了子視圖控制器的 willMoveToParentViewController: 方法。 必須自己調用 didMoveToParentViewController: 方法的原因是,只有在將子視圖嵌入容器的視圖層次結構后,方法才能被調用。 使用自動布局時,在將子視圖添加到容器的視圖層次結構后,在容器和子對象之間設置約束。 約束只會影響子視圖控制器的根視圖的大小和位置。 請勿更改子視圖控制器的根視圖或者其視圖層次結構。 #### 刪除子視圖控制器 要從容器中刪除子視圖控制器,請通過執行以下操作來刪除視圖控制器之間的父子關系: 1. 調用子視圖控制器的 willMoveToParentViewController: 方法 ,參數為 nil 。 2. 刪除子視圖控制器的根視圖配置的約束。 3. 從容器的視圖層次結構中移除子視圖控制器的根視圖。 4. 調用子視圖控制器的 removeFromParentViewController 方法來結束父子關系。 刪除子視圖控制器會永久切斷父級和子級之間的關系。 只有當您不再需要引用子視圖控制器時,才能移除子視圖控制器。 例如,當新導航控制器被推入導航堆棧時,導航控制器不會移除其當前的子視圖控制器。 只有當它們從堆棧中彈出時才會將其移除。 清單5-2顯示了如何從容器中移除子視圖控制器。調用子視圖控制器的willMoveToParentViewController:方法,參數為 nil;為其提供了為更改做準備的機會。調用 removeFromParentViewController 方法同時會調用 didMoveToParentViewController: 方法,參數為 nil。 將父視圖控制器設置為 nil,就可以將子視圖從容器中刪除。 ###### Listing 5-2 刪除子視圖控制器 ~~~ - (void) hideContentController: (UIViewController*) content { [content willMoveToParentViewController:nil]; [content.view removeFromSuperview]; [content removeFromParentViewController]; } ~~~ #### 子視圖控制器之間的過渡 當想要用動畫的形式完成一個子視圖控制器替換另一個時,將子視圖控制器的添加和刪除合并到轉換動畫過程中。 在動畫之前,請確保兩個子視圖控制器都是容器視圖控制器的一部分,但讓當前的子節點知道它即將消失。 在動畫中,將新的子節點的視圖移動到正確位并移除舊的子節點的視圖。 動畫完成后,完成子視圖控制器的移除。 清單5-3展示了如何使用轉換動畫將一個子視圖控制器轉換為另一個子視圖控制器的示例。在這個例子中,新的視圖控制器被以動畫方式移動到由現有的子視圖控制器所占用的矩形區域中,該控制器被移動到屏幕外。在動畫完成之后,completion block 從容器中刪除子視圖控制器。 在這個例子中,` transitionFromViewController:toViewController:duration:options:animations:completion: `方法會自動更新容器的視圖層次,所以你不需要自己添加和移除視圖。 ###### 清單 5-3 兩個子視圖控制器之間的轉換 ~~~ - (void)cycleFromViewController: (UIViewController*) oldVC toViewController: (UIViewController*) newVC { // Prepare the two view controllers for the change. [oldVC willMoveToParentViewController:nil]; [self addChildViewController:newVC]; // Get the start frame of the new view controller and the end frame // for the old view controller. Both rectangles are offscreen. newVC.view.frame = [self newViewStartFrame]; CGRect endFrame = [self oldViewEndFrame]; // Queue up the transition animation. [self transitionFromViewController: oldVC toViewController: newVC duration: 0.25 options:0 animations:^{ // Animate the views to their final positions. newVC.view.frame = oldVC.view.frame; oldVC.view.frame = endFrame; } completion:^(BOOL finished) { // Remove the old view controller and send the final // notification to the new view controller. [oldVC removeFromParentViewController]; [newVC didMoveToParentViewController:self]; }]; } ~~~ #### 管理子節點的外觀更新 在將一個子節點添加到容器后,容器會自動將與外觀相關的消息轉發給子節點。一般來說是必要的的行為,因為它確保所有事件都被正確地發送。但是,有時候默認的行為可能會以一種對您的容器沒有意義的順序發送這些事件。例如,如果多個子節點同時更改它們的視圖狀態,那么您可能需要調整這些更改,以便外觀回調在同一時間以更合理的順序發生。 要接管外觀回調的責任,請覆蓋容器視圖控制器中的 `shouldAutomaticallyForwardAppearanceMethods`方法,并返回 NO ,如清單 5-4 所示。 返回 NO 讓 UIKit 知道你的容器視圖控制器通知其子的外觀變化。 ###### 清單 5-4 禁用自動轉發外觀消息 ~~~ - (BOOL) shouldAutomaticallyForwardAppearanceMethods { return NO; } ~~~ 出現轉場時,根據需要調用子節點的 `beginAppearanceTransition:animated:` 或 `endAppearanceTransition `方法。 例如,如果您的容器有一個由 child 屬性引用的單個子節點,那么您的容器會將這些消息轉發給子項,如清單 5-5 所示。 ###### 清單 5-5 轉發容器出現或消失的外觀消息 ~~~ -(void) viewWillAppear:(BOOL)animated { [self.child beginAppearanceTransition: YES animated: animated]; } -(void) viewDidAppear:(BOOL)animated { [self.child endAppearanceTransition]; } -(void) viewWillDisappear:(BOOL)animated { [self.child beginAppearanceTransition: NO animated: animated]; } -(void) viewDidDisappear:(BOOL)animated { [self.child endAppearanceTransition]; } ~~~ ### 構建容器視圖控制器的建議 設計、開發和測試一個新的容器視圖控制器需要時間。盡管單個功能很簡單,但是作為一個整體的控制器是相當復雜的。在實現您自己的容器類時,請考慮以下技巧: * **只訪問子視圖控制器的根視圖**。容器應該只訪問每個子節點的根視圖,即子節點的 view 屬性返回的視圖。它不應該訪問任何一個子節點的其他視圖。 * **子視圖控制器應該對它們的容器有最少的了解**。子視圖控制器應該把焦點放在它自己的內容上。如果容器允許它的行為受到一個孩子的影響,那么它應該使用委托設計模式來管理這些交互。 * **優先使用常規視圖設計容器**。使用常規視圖(而不是來自子視圖控制器的視圖)可以讓您有機會在一個簡化的環境中測試布局約束和動畫轉換。當常規視圖按預期工作時,將它們放到您的子視圖控制器的視圖中。 * ### 將控制權委托給子視圖控制器 容器視圖控制器可以將其自身外觀的某些方面委托給一個或多個子視圖控制器。你可以用以下方法來委派控制: * 讓一個子視圖控制器確定狀態欄的樣式。 要將狀態欄外觀委托給子級,請覆蓋容器視圖控制器中的 childViewControllerForStatusBarStyle 和 childViewControllerForStatusBarHidden 方法中的一個或兩個。 * 讓子視圖控制器指定自己預設的尺寸。 具有靈活布局的容器可以使用子節點的 preferredContentSize 屬性來幫助確定子節點的大小。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看