iOS文檔補完計劃--UIViewController

目錄

  • UIViewController
    • 職責
    • 視圖管理
    • 處理與視圖相關的通知
    • 實現容器視圖控制器
    • 內存管理
    • 生命週期
  • 以代碼的方式創建一個控制器
    • initWithNibName:bundle:
    • initWithCoder:
  • 管理視圖
    • view
    • viewLoaded
    • loadView
    • viewDidLoad
    • loadViewIfNeeded
    • viewIfLoaded
    • title
    • preferredContentSize
  • 呈現視圖控制器
    • modalPresentationStyle
    • modalTransitionStyle
    • showViewController:sender:
    • presentViewController:animated:completion:
    • dismissViewControllerAnimated:completion:
  • 響應View事件
    • View XX Appear
    • beingDismissed && beingPresented
    • Moving XX ParentViewController
  • 安全區域
    • additionalSafeAreaInsets
    • viewSafeAreaInsetsDidChange
  • 佈局視圖
    • edgesForExtendedLayout
    • extendedLayoutIncludesOpaqueBars
    • updateViewConstraints
    • viewWill/DidLayoutSubviews
  • 子視圖控制器
    • childViewControllers
    • addChildViewController:
    • removeFromParentViewController
    • transitionFromViewController:toViewController:duration:options:animations:completion:
    • shouldAutomaticallyForwardAppearanceMethods
    • AppearanceTransition
  • 響應容器事件
    • willMoveToParentViewController
    • didMoveToParentViewController
  • 獲取其他控制器
    • presentingViewController && presentedViewController
    • parentViewController
    • navigationController
    • splitViewController
    • tabBarController
  • 處理內存警告
    • didReceiveMemoryWarning
  • 協調系統手勢
    • preferredScreenEdgesDeferringSystemGestures
    • childViewControllerForScreenEdgesDeferringSystemGestures
  • 管理狀態欄
    • childViewControllerForStatusBarStyle
    • childViewControllerForStatusBarHidden
    • preferredStatusBarStyle
    • prefersStatusBarHidden
    • modalPresentationCapturesStatusBarAppearance
    • preferredStatusBarUpdateAnimation
    • setNeedsStatusBarAppearanceUpdate
  • 配置導航入口
    • navigationItem
    • hidesBottomBarWhenPushed
    • toolbarItems
    • tabBarItem
  • 編輯行爲
    • editing
    • setEditing:animated:
    • editButtonItem

UIViewController

  • 職責
  1. 更新視圖內容
  2. 響應交互
  3. 調整入口View布
  4. 與程序中其他對象(包括其他控制器)進行協調

UIViewController作爲UIResponder、被插入響應鏈之間。如果其持有的視圖中沒有一個可以處理某事件、控制器可以選擇自行處理或者傳遞給父視圖。

控制器很少單獨被使用、我們通常使用多個控制器進行相互的跳轉作業。

  • 視圖管理

根View主要充當視圖層次結構的其餘部分的容器。
根View的大小和位置由擁有它的對象決定,該對象要麼是視圖控制器,要麼是應用程序的Window。
Window所擁有的視圖控制器是應用程序的根View控制器,它的視圖是用來填充Window的。

View屬性是懶加載的、有幾種方式可以指定ViewController的View:

  1. Storyboard
    可以指定視圖及其與視圖控制器的連接。
    你也指定視圖控制器之間的關係和segue。
  2. Nib
    使用Nib文件爲視圖控制器指定單個視圖控制器的視圖。
    但不允許定義segue或視圖控制器之間的關係。
  3. loadView方法
    以代碼方式創建視圖層次結構,並將該層次結構的根視圖分配給視圖控制器的View屬性

所有的方式都能導向相同的結果:創建VIew並且通過ViewController.view屬性進行公開。

需要注意的是

多個Controller使用同一個Storyboard或者Nib作爲View屬性時、他們會持有單獨的副本。
而代碼方式、你必須確保View不會被多個VC持有。

  • 處理與視圖相關的通知
視圖的可見性

當視圖的可見性發生變化時,視圖控制器會自動調用它自己的方法,以便子類可以對變化做出響應。比如viewWillAppear在展示之前進行設置、viewWillDisappear:在消失之前進行狀態保存或更改。

  • 實現容器視圖控制器

我們的日常開發中常有這樣一種需求,通過切換標籤來切換不同的頁面,如果在一個 controller 管理這些 view 的話,代碼就顯得耦合度過高,也與 Apple 的 MVC 模式不符合,Apple 推薦一個 controller 管理一個 view。這樣做有三個好處:

1.無疑,對頁面中的邏輯更加分明瞭。相應的View對應相應的ViewController。
2.當某個子View沒有顯示時,將不會被Load,減少了內存的使用。
3.當內存緊張時,沒有Load的View將被首先釋放,優化了程序的內存釋放機制。
4.在子VC上調用self.navigationController可以傳遞給父VC。(UIPageController上特別好用)

像這樣使用
//添加
[self addChildViewController:sfViewControllr];
[self.view addSubview:sfViewControllr.view];
sfViewControllr.view.frame = CGRectMake(0, 300, 1, 1);

//移除
[sfViewControllr didMoveToParentViewController:self];

如果只是 [self.view addSubview:sfViewControllr.view]; 的方式用另一個 controller 來控制,但是這樣會產生一個新的問題:直接 add 進去的subView不在 viewController的 view hierarchy 內,事件不會正常傳遞,如:旋轉、觸摸等,屬於危險操作違背CocoaTouch開發的設計MVC原則,viewController應該且只應該管理一個view hierarchy。

  • 內存管理

內存是iOS中的關鍵資源,視圖控制器提供了內置支持,在關鍵時刻減少內存佔用。UIViewController類通過它的didReceiveMemoryWarning方法提供一些低內存條件的自動處理,這些方法釋放不需要的內存。

  • 生命週期
  1. +[ViewController load]
  2. +[ViewController initialize]
  3. -[ViewController init]
  4. -[ViewController loadView]
  5. -[ViewController viewDidLoad]
  6. -[ViewController viewWillAppear:]
  7. -[ViewController updateViewConstraints]
  8. -[ViewController viewWillLayoutSubviews]
  9. -[ViewController viewDidLayoutSubviews]
  10. -[ViewController viewDidAppear:]
  11. -[ViewController dealloc]

其中1和2嚴格意義上來講應該不算在內


以代碼的方式創建一個控制器

  • - initWithNibName:bundle:

通過代碼的方式實例化一個IB方式創建的控制器

- (instancetype)initWithNibName:(NSString *)nibNameOrNil 
                         bundle:(NSBundle *)nibBundleOrNil;

TestViewController *tvc = [[TestViewController alloc] initWithNibName:@"xx" bundle:nil]; // 注意xib名字不要後綴

需要指定xx.xib的file’s owner的Custom Class爲TestViewController,並且把file’s owner的view指定爲其中的一個view

  • - initWithCoder:

在IB中創建的類、但在xocde中被實例化時被調用

- (instancetype)initWithCoder:(NSCoder *)aDecoder;

管理視圖

  • view

容器視圖

@property(nonatomic, strong) UIView *view;
  1. 這個屬性是來加載的、當你訪問時如果爲nil、將調用loadView方法並返回view
  2. 每一個VC、都必須是該View的唯一一個持有者。(例外情況是通過addChildViewController:方法添加後、將vc.view add給另一個vc)
  3. 你可以通過isViewLoaded方法來檢測當前vc是否已經持有視圖。(這樣不會觸發懶加載)。
  4. VC有權在低內存情況下以及VC最終釋放時、釋放這個屬性。
  • viewLoaded

self.view是否有值

@property(nonatomic, readonly, getter=isViewLoaded) BOOL viewLoaded;

這個屬性的檢測不會觸發view屬性的懶加載。

  • - loadView

創建容器視圖

- (void)loadView;

view屬性被訪問但本身沒有值時觸發、你可以在這裏自定義view屬性的視圖。

  1. 永遠不要直接調用這個方法。
  2. 如果使用nib、該方法從nib中加載視圖。如果不是、則直接創建一個UIView
  3. 如果使用IB來創建VC、不要覆蓋這個方法。
  4. 如果自定義view。您創建的視圖應該是唯一的實例,不應該與任何其他視圖控制器對象共享。此方法的自定義實現不應調用super。
  5. 如果想對view進行其餘的動作(添加subVIew等等)、請在viewDidLoad`中執行。

通常用在進到vc就要切換view的時候使用、比如進來就是一張圖片啊、webView啊之類。

  • - viewDidLoad

loadView後執行。表示此時已經有view屬性

- (void)viewDidLoad;

不管視圖層次結構是從nib文件加載的還是在loadView方法中以編程方式創建的,都會調用此方法。
通常在這裏對view進行進一步配置。

  • loadViewIfNeeded

主動嘗試調用loadView

- (void)loadViewIfNeeded;

正常如果我們主動調用[self loadView];是不會觸發viewDidLoad的、但這個方法可以。
不過似乎必須要[self isViewLoaded] == NO才行

  • viewIfLoaded

返回vc的view。並且不會觸發懶加載

@property(nonatomic, readonly, strong) UIView *viewIfLoaded;

如果沒有則返回nil

  • title

標題

@property(nonatomic, copy) NSString *title;

如果VC有一個有效的導航項或標籤欄項,爲該屬性賦值將更新這些對象的標題文本。
相當於同時設置了tabBarItem.titlenavigationItem.title

  • preferredContentSize

我們可以使用preferredContentSize來設置我們期望的childViewController的界面的大小

@property(nonatomic) CGSize preferredContentSize;

沒太理解怎麼用、有明白的大佬舉個例子?
似乎在ipad上有用


呈現視圖控制器

  • modalPresentationStyle

模態跳轉的樣式

@property(nonatomic, assign) UIModalPresentationStyle modalPresentationStyle;

UIModalPresentationStyle爲一個枚舉類型

在iPhone和iPod touch上面系統始終已UIModalPresentationFullScreen模式顯示presented VC。(哈哈哈。很氣、我試了半天差了好多資料最後看到這句話)
typedefNS_ENUM(NSInteger, UIModalPresentationStyle) {

        UIModalPresentationFullScreen =0,//全屏覆蓋

        UIModalPresentationPageSheet,//彈出VC時,presented VC的高度和當前屏幕高度相同,寬度和豎屏模式下屏幕寬度相同,剩餘未覆蓋區域將會變暗並阻止用戶點擊,這種彈出模式下,豎屏時跟 UIModalPresentationFullScreen的效果一樣,橫屏時候兩邊則會留下變暗的區域。

        UIModalPresentationFormSheet,// presented VC的高度和寬度均會小於屏幕尺寸,presented VC居中顯示,四周留下變暗區域。

        UIModalPresentationCurrentContext,//這種模式下,presented VC的彈出方式和presenting VC的父VC的方式相同。

        UIModalPresentationCustom,//自定義視圖展示風格,由一個自定義演示控制器和一個或多個自定義動畫對象組成。符合UIViewControllerTransitioningDelegate協議。使用視圖控制器的transitioningDelegate設定您的自定義轉換。

        UIModalPresentationOverFullScreen,//如果視圖沒有被填滿,底層視圖可以透過

        UIModalPresentationOverCurrentContext,//視圖全部被透過

        UIModalPresentationPopover,

        UIModalPresentationNone ,

    };
  • modalTransitionStyle

設置過渡動畫樣式

@property(nonatomic, assign) UIModalTransitionStyle modalTransitionStyle;

在通過presentViewController:animated:completion:進行模態跳轉時的專場動畫樣式。默認UIModalTransitionStyleCoverVertical

UIModalTransitionStyle是一個枚舉類型

typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {

        UIModalTransitionStyleCoverVertical =0,//從底部滑入

        UIModalTransitionStyleFlipHorizontal,//水平翻轉

        UIModalTransitionStyleCrossDissolve,//交叉溶解

        UIModalTransitionStylePartialCurl  NS_ENUM_AVAILABLE_IOS(3_2),//翻頁效果

};
  • showViewController:sender:

大一統的跳轉方法

- (void)showViewController:(UIViewController *)vc 
                    sender:(id)sender;

- (void)showDetailViewController:(UIViewController *)vc 
                          sender:(id)sender;

全能型界面切換的方法,它能根據當前的試圖控制器情況來決定是用navVC的push方法還是普通VC的Modal方式來切換界面。

showViewController是蘋果“大一統”編程思想的體現,無論是在UINavigationController還是在UISplitViewController管理下,都可以使用showViewController去跳轉。系統底層會實現兩種管理模式下的對應跳轉。另外如果這兩種方式都未實現,就會以modal方式跳轉。

  1. 當前界面是Nav的子VC時
    它會用push方式切換。
  2. 當前界面爲Modal的界面,
    就會用modal方式切換。

但也有些缺陷、比如不能設置是否執行動畫、獲取不到完成的block。

一般情況下,horizontally compact(iphone) 環境下,意義不大(因爲不太需要考慮UISplitViewController)。
  • - presentViewController:animated:completion:

以模態方式呈現一個VC

- (void)presentViewController:(UIViewController *)viewControllerToPresent 
                     animated:(BOOL)flag 
                   completion:(void (^)(void))completion;

在水平規則環境中,視圖控制器以modalPresentationStyle屬性指定的樣式表示。
任何情況下都可以通過modalTransitionStyle屬性進行轉場設置。
viewDidAppear之後調用completion回調。

  • - dismissViewControllerAnimated:completion:

退出一個由模態方式展示的VC

- (void)dismissViewControllerAnimated:(BOOL)flag 
                           completion:(void (^)(void))completion;

viewDidDisappear之後調用completion回調。


響應View事件

  • View XX Appear

視圖的顯示與隱藏

- (void)viewWillAppear:(BOOL)animated;    // 視圖即將顯示時調用
- (void)viewDidAppear:(BOOL)animated;     // 視圖已經顯示時調用
- (void)viewWillDisappear:(BOOL)animated; // 視圖將要消失時調用
- (void)viewDidDisappear:(BOOL)animated; // 視圖已經消失時調用

這張圖應該很清楚了


.h文件裏說這四個方法默認什麼都不做、但是文檔裏說務必調用super方法

  • beingDismissed && beingPresented

視圖是否正在消失/顯示

@property(nonatomic, readonly, getter=isBeingPresented) BOOL beingPresented NS_AVAILABLE_IOS(5_0); //正在顯示
@property(nonatomic, readonly, getter=isBeingDismissed) BOOL beingDismissed NS_AVAILABLE_IOS(5_0);//正在消失
  • Moving XX ParentViewController

視圖是否正在從父VC來/向父VC去

@property(nonatomic, readonly, getter=isMovingToParentViewController) BOOL movingToParentViewController NS_AVAILABLE_IOS(5_0); //向父VC去
@property(nonatomic, readonly, getter=isMovingFromParentViewController) BOOL movingFromParentViewController NS_AVAILABLE_IOS(5_0); //從父VC來

安全區域

  • additionalSafeAreaInsets

修改安全區域的內嵌程度

@property(nonatomic) UIEdgeInsets additionalSafeAreaInsets;

比如如果SafeAreaInset值爲(20,0,0,0),那麼頁面上的TableVIew可能會下移20個單位。
此時設置additionalSafeAreaInsets屬性值爲(-20,0,0,0),則SafeAreaInsets不會對adjustedContentInset值產生影響。以便正常顯示。
有興趣可以看看《iOS 11 安全區域適配總結》

  • - viewSafeAreaInsetsDidChange

當VC的safeAreaInsets發生改變是被調用

- (void)viewSafeAreaInsetsDidChange;

佈局視圖

  • edgesForExtendedLayout

指定view的邊(上、下、左、右)延伸到整個屏幕

@property(nonatomic, assign) UIRectEdge edgesForExtendedLayout;

默認值是UIRectEdgeAll, 意味着view會被拓展到整個屏幕。

它只有當viewController被嵌到別的container view controller中時纔會起作用

《edgesForExtendedLayout淺淡》

  • extendedLayoutIncludesOpaqueBars

如果status bar是不透明的,view不會被延伸到status bar,除非extendedLayoutIncludesOpaqueBars = YES;

@property(nonatomic, assign) BOOL extendedLayoutIncludesOpaqueBars;

默認爲NO。在iOS 7.0中,bars默認是半透明的。

  • updateViewConstraints

當自身view屬性的佈局被修改時被自動調用

- (void)updateViewConstraints;

這個方法默認的實現是調用對應View的 -updateConstraints

調用[super updateViewConstraints]作爲實現的最後一步。
  • viewWill/DidLayoutSubviews

重新佈局子View前/後調用

- (void)viewWillLayoutSubviews NS_AVAILABLE_IOS(5_0);
- (void)viewDidLayoutSubviews NS_AVAILABLE_IOS(5_0);
這兩個方法的默認實現什麼都不做

其中viewDidLayoutSubviews可以獲取子控件正確的frame


子視圖控制器

具體的作用可以回去看看《UIViewController》 >>>《實現容器視圖控制器》部分的解釋。

  • childViewControllers

存放子VC的數組

@property(nonatomic, readonly) NSArray<__kindof UIViewController *> *childViewControllers;
  • - addChildViewController:

添加子VC

- (void)addChildViewController:(UIViewController *)childController;
  • - removeFromParentViewController

從父VC上移除

- (void)removeFromParentViewController;
  • - transitionFromViewController:toViewController:duration:options:animations:completion:

通過動畫的方式操作兩個子VC

- (void)transitionFromViewController:(UIViewController *)fromViewController 
                    toViewController:(UIViewController *)toViewController 
                            duration:(NSTimeInterval)duration 
                             options:(UIViewAnimationOptions)options 
                          animations:(void (^)(void))animations 
                          completion:(void (^)(BOOL finished))completion;

《iOS 中使用ViewController控制轉場的各種方法》

  • shouldAutomaticallyForwardAppearanceMethods

是否將appearance callbacks事件傳遞給子VC

@property(nonatomic, readonly) BOOL shouldAutomaticallyForwardAppearanceMethods;

appearance callbacks基本上指viewWillDisappear,viewDidDisappear之類方法。
默認爲YES、你可以重載以禁用

- (BOOL)shouldAutomaticallyForwardAppearanceMethods
{
    return NO;
}
  • AppearanceTransition

調起指定的appearance callbacks

- (void)beginAppearanceTransition:(BOOL)isAppearing 
                         animated:(BOOL)animated;
- (void)endAppearanceTransition;

動傳遞的時候你並不能直接去調用childviewWillAppear或者viewDidAppear這些方法,而是需要使用 beginAppearanceTransition:animated:endAppearanceTransition接口來間接觸發那些appearance callbacks
且begin和end必須成對出現

[content beginAppearanceTransition:YES animated:animated]觸發content的viewWillAppear
[content beginAppearanceTransition:NO animated:animated]觸發content的viewWillDisappear
和他們配套的[content endAppearanceTransition]分別觸發viewDidAppearviewDidDisappear


響應容器事件

  • - willMoveToParentViewController

將要添加到容器VC時調用

- (void)willMoveToParentViewController:(UIViewController *)parent;

BVC通過addChildViewControllerA、接口建立了邏輯上的父子關係,BVC可以通過parentViewController,訪問AVCaddChildViewController:接口的邏輯中會自動調用 [BVC willMoveToParentViewController:self];

  • didMoveToParentViewController

從容器VC上移除時調用

- (void)didMoveToParentViewController:(UIViewController *)parent;

同上、在調用removeFromParentViewController時內部會調用[BVC didMoveToParentViewController:nil]


獲取其他控制器

  • presentingViewController && presentedViewController

presen別人的控制器、被presen的控制器

@property(nonatomic, readonly) UIViewController *presentingViewController;//來自
@property(nonatomic, readonly) UIViewController *presentedViewController;//去往
假設從A控制器通過present的方式跳轉到了B控制器,那麼 A.presentedViewController 就是B控制器;B.presentingViewController 就是A控制器。
  • parentViewController

父VC

@property(nonatomic, weak, readonly) UIViewController *parentViewController;
  • navigationController

持有該VC的導航欄控制器

@property(nonatomic, readonly, strong) UINavigationController *navigationController;
  • splitViewController

持有該VC的分屏控制器

@property(nonatomic, readonly, strong) UISplitViewController *splitViewController;
  • tabBarController

持有該VC的tabBar控制器

@property(nonatomic, readonly, strong) UITabBarController *tabBarController;

處理內存警告

  • didReceiveMemoryWarning

當應用程序收到內存警告的時候會調用這個方法 ,做相應的解決內存警告的操作

- (void)didReceiveMemoryWarning;

必須調用super實現


協調系統手勢

  • preferredScreenEdgesDeferringSystemGestures

協調系統邊緣的滑動手勢

@property(nonatomic, readonly) UIRectEdge preferredScreenEdgesDeferringSystemGestures;

有時候你的App需要控制從狀態欄下拉或者底部欄上滑,這個會跟系統的下拉通知中心手勢和上滑控制中心手勢衝突。
如果你要優先自己處理手勢可以將系統手勢延遲。
《解決ios11上 從狀態欄下拉或底部欄上滑,跟系統的下拉通知中心手勢和上滑控制中心手勢衝突》

  • childViewControllerForScreenEdgesDeferringSystemGestures

控制子試圖控制器是否允許開發者控制edge protect的開啓或是關閉

@property(nonatomic, readonly) UIViewController *childViewControllerForScreenEdgesDeferringSystemGestures;

如果實現了這個方法並且返回值不爲空那麼子VC的edge protect設置就會遵循父VC的設置,跟隨父VC是否延遲執行系統手勢。

《關於iPhone X下Home鍵的隱藏和延遲響應》


管理狀態欄

  • childViewControllerForStatusBarStyle

應該使用哪一個VC來確定狀態欄的Style

@property(nonatomic, readonly) UIViewController *childViewControllerForStatusBarStyle;
以下解釋轉自《iOS狀態欄詳解》

運用這個函數就可以解決嵌套UINavigationController設置樣式無效的問題。

解釋一下爲什麼嵌套UINavigationControllerviewControllerpreferredStatusBarStyle函數設置無效:
在我們嵌套了UINavigationController的時候,我們的
AppDelegate.window.rootViewController
通常是我們創建的navigationController,這時首先會調用的是navigationController中的childViewControllerForStatusBarStyle函數,因爲默認返回nil,那麼接下來就會調用navigationController本身的preferredStatusBarStyle函數,所以我們在viewController中通過preferredStatusBarStyle函數設置的狀態欄樣式就不會被調用發現,所以也就無效了。

所以我們要自己創建一個繼承於UINavigationcontroller
NavigationController,在這個子類中重寫
childViewControllerForStatusBarStyle函數

- (UIViewController *)childViewControllerForStatusBarStyle{
    return self.topViewController;
}

這樣navigationController中的childViewControllerForStatusBarStyle函數會返回navigationController中最上層的viewController,那麼viewController中的preferredStatusBarStyle函數的設置就會被系統獲知。

  • childViewControllerForStatusBarHidden

應該使用哪一個VC來確定狀態欄的顯示/隱藏

@property(nonatomic, readonly) UIViewController *childViewControllerForStatusBarHidden;

函數的使用原理同上,不再贅述。

  • preferredStatusBarStyle

狀態欄樣式

@property(nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle;

UIStatusBarStyle是一個枚舉類型

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
//默認樣式,黑字透明狀態欄,適合用於背景色爲亮色的頁面
    UIStatusBarStyleDefault                                     = 0, // Dark content, for use on light backgrounds
//白字透明狀態欄,適合用於背景色爲暗色的頁面
    UIStatusBarStyleLightContent     NS_ENUM_AVAILABLE_IOS(7_0) = 1, // Light content, for use on dark backgrounds
    
// iOS7.0以前黑底白字,iOS7以後跟UIStatusBarStyleLightContent效果一樣
    UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
// iOS7.0以前啓動頁爲灰底白字,iOS7以後跟UIStatusBarStyleLightContent效果一樣
    UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
} __TVOS_PROHIBITED;

使用起來、需要在具體的VC中

- (UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}
  • prefersStatusBarHidden

狀態欄的顯示/隱藏

@property(nonatomic, readonly) BOOL prefersStatusBarHidden;

使用起來、需要在具體的VC中

- (BOOL)prefersStatusBarHidden{
    return YES;
}
  • modalPresentationCapturesStatusBarAppearance

在非全屏的模態中、獲得狀態欄控制權

@property(nonatomic, assign) BOOL modalPresentationCapturesStatusBarAppearance;

modalPresentationCapturesStatusBarAppearance是專門爲強迫症患者量身定製的,只需要重寫這個屬性並返回true,你就可以在任何形式的Model Presentation中獲得對 Status Bar Style的控制權了。

  • preferredStatusBarUpdateAnimation

狀態欄更新時的動畫

@property(nonatomic, readonly) UIStatusBarAnimation preferredStatusBarUpdateAnimation;

重寫此方法設置狀態欄更新時候的動畫

  • setNeedsStatusBarAppearanceUpdate

準備更新狀態欄

- (void)setNeedsStatusBarAppearanceUpdate;

當你需要更新狀態欄時、調用他。支持動畫漸變


配置導航入口

  • navigationItem

分欄控制器按鈕

@property(nonatomic, readonly, strong) UINavigationItem *navigationItem;

可以用來設置導航欄上的分欄按鈕

UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"nav_scan_icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(rightItemAction)];
    self.navigationItem.rightBarButtonItem = rightItem;

UINavigationItem的唯一實例、通過懶加載的方式生產。

  • hidesBottomBarWhenPushed

在VC展示時、下方Tabbar是否隱藏

@property(nonatomic) BOOL hidesBottomBarWhenPushed;

通常都是在BaseViewController裏設置成YES了。

  • toolbarItems

更改工具欄

- (void)setToolbarItems:(NSArray<UIBarButtonItem *> *)toolbarItems 
               animated:(BOOL)animated;
@property(nonatomic, strong) NSArray<__kindof UIBarButtonItem *> *toolbarItems;
  • tabBarItem

Tabbar上的按鈕

@property(nonatomic, strong) UITabBarItem *tabBarItem;

編輯行爲

  • editing

是否允許用戶進行編輯

@property(nonatomic, getter=isEditing) BOOL editing;
  • setEditing:animated:

更新Edit|Done按鈕item的外觀

- (void)setEditing:(BOOL)editing 
          animated:(BOOL)animated;

當設置controllerediting屬性,會自動觸發setEditing:animated屬性,這個時候通過myController editButtonItem獲得的編輯按鈕會自動從edit變成Done,這個通常使用在navigation Controller

  • editButtonItem

返回Edit|Done按鈕。

@property(nonatomic, readonly) UIBarButtonItem *editButtonItem;

比如設置一個右上角按鈕爲editButton的話代碼如下

myViewController.navigationItem.rightBarButtonItem=[myViewController editButtonItem];


參考資料

官方文檔-UIViewController
UIViewController詳解
iOS UIViewController
iOS開發之使用addChildViewController:給控制器添加子控制器
addChildViewController方法詳解
UIViewController全部API的學習
iOS開發之loadView、viewDidLoad及viewDidUnload的關係
iOS 中使用ViewController控制轉場的各種方法
edgesForExtendedLayout淺淡
解決ios11上 從狀態欄下拉或底部欄上滑,跟系統的下拉通知中心手勢和上滑控制中心手勢衝突
關於iPhone X下Home鍵的隱藏和延遲響應
iOS:UIToolBar、toolbarItems、BarButtonItem的幾種關係

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章