目錄
-
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
-
職責
- 更新視圖內容
- 響應交互
- 調整入口View布
- 與程序中其他對象(包括其他控制器)進行協調
UIViewController
作爲UIResponder
、被插入響應鏈之間。如果其持有的視圖中沒有一個可以處理某事件、控制器可以選擇自行處理或者傳遞給父視圖。
控制器很少單獨被使用、我們通常使用多個控制器進行相互的跳轉作業。
-
視圖管理
根View主要充當視圖層次結構的其餘部分的容器。
根View的大小和位置由擁有它的對象決定,該對象要麼是視圖控制器,要麼是應用程序的Window。
Window所擁有的視圖控制器是應用程序的根View控制器,它的視圖是用來填充Window的。
View屬性是懶加載的、有幾種方式可以指定ViewController的View:
- Storyboard
可以指定視圖及其與視圖控制器的連接。
你也指定視圖控制器之間的關係和segue。 - Nib
使用Nib文件爲視圖控制器指定單個視圖控制器的視圖。
但不允許定義segue或視圖控制器之間的關係。 - 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
方法提供一些低內存條件的自動處理,這些方法釋放不需要的內存。
-
生命週期
- +[ViewController load]
- +[ViewController initialize]
- -[ViewController init]
- -[ViewController loadView]
- -[ViewController viewDidLoad]
- -[ViewController viewWillAppear:]
- -[ViewController updateViewConstraints]
- -[ViewController viewWillLayoutSubviews]
- -[ViewController viewDidLayoutSubviews]
- -[ViewController viewDidAppear:]
- -[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;
- 這個屬性是來加載的、當你訪問時如果爲nil、將調用
loadView
方法並返回view
。 - 每一個VC、都必須是該View的唯一一個持有者。(例外情況是通過
addChildViewController:
方法添加後、將vc.view add給另一個vc) - 你可以通過
isViewLoaded
方法來檢測當前vc是否已經持有視圖。(這樣不會觸發懶加載)。 - VC有權在低內存情況下以及VC最終釋放時、釋放這個屬性。
-
viewLoaded
self.view
是否有值
@property(nonatomic, readonly, getter=isViewLoaded) BOOL viewLoaded;
這個屬性的檢測不會觸發view
屬性的懶加載。
-
- loadView
創建容器視圖
- (void)loadView;
當view
屬性被訪問但本身沒有值時觸發、你可以在這裏自定義view
屬性的視圖。
- 永遠不要直接調用這個方法。
- 如果使用
nib
、該方法從nib
中加載視圖。如果不是、則直接創建一個UIView
。 - 如果使用IB來創建VC、不要覆蓋這個方法。
- 如果自定義
view
。您創建的視圖應該是唯一的實例,不應該與任何其他視圖控制器對象共享。此方法的自定義實現不應調用super。 - 如果想對
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.title
和navigationItem.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方式來切換界面。
- 當前界面是Nav的子VC時
它會用push方式切換。 - 當前界面爲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中時纔會起作用
-
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;
動傳遞的時候你並不能直接去調用child
的viewWillAppear
或者viewDidAppear
這些方法,而是需要使用 beginAppearanceTransition:animated:
和endAppearanceTransition
接口來間接觸發那些appearance callbacks
且begin和end必須成對出現
。
[content beginAppearanceTransition:YES animated:animated]
觸發content的viewWillAppear
[content beginAppearanceTransition:NO animated:animated]
觸發content的viewWillDisappear
,
和他們配套的[content endAppearanceTransition]
分別觸發viewDidAppear
和viewDidDisappear
。
響應容器事件
-
- willMoveToParentViewController
將要添加到容器VC時調用
- (void)willMoveToParentViewController:(UIViewController *)parent;
將BVC
通過addChildViewController
給A
、接口建立了邏輯上的父子關係,BVC
可以通過parentViewController
,訪問AVC
,addChildViewController:
接口的邏輯中會自動調用 [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是否延遲執行系統手勢。
管理狀態欄
-
childViewControllerForStatusBarStyle
應該使用哪一個VC來確定狀態欄的Style
@property(nonatomic, readonly) UIViewController *childViewControllerForStatusBarStyle;
以下解釋轉自《iOS狀態欄詳解》
運用這個函數就可以解決嵌套UINavigationController
設置樣式無效的問題。
解釋一下爲什麼嵌套
UINavigationController
的viewController
的preferredStatusBarStyle
函數設置無效:
在我們嵌套了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;
-
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;
當設置controller
的editing
屬性,會自動觸發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的幾種關係