ViewController类中得方法和属性的用途
?
1、?wantsFullScreenLayout
只要在UIViewController上設(shè)置wantsFullScreenLayout=true ,那么狀態(tài)欄的高度就不會被算在視圖里,也就是說有沒有狀態(tài)欄y坐標(biāo)始終都是從0算起。?如果沒有設(shè)置這個的話,旋轉(zhuǎn)屏幕并且隱藏顯示狀態(tài)欄(statusBarHidden)時會出現(xiàn)20像素的白邊或者,view跑出屏幕20像素。(這個屬性在IOS7中棄用 edgesForExtendedLayout代替)
?
@property(nonatomic,assign) BOOL wantsFullScreenLayout NS_DEPRECATED_IOS(3_0, 7_0); // Deprecated in 7_0, Replaced by the following:
?
@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll
?
2、edgesForExtendedLayout
使用?edgesForExtendedLayout?指定視圖的哪條邊需要擴(kuò)展,不用理會操作欄的透明度。這個屬性的默認(rèn)值是UIRectEdgeAll。
extendedLayoutIncludesOpaqueBars
如果你使用了不透明的操作欄,設(shè)置?edgesForExtendedLayout?的時候也請將extendedLayoutIncludesOpaqueBars?的值設(shè)置為No(默認(rèn)值是YES)。
?
3、automaticallyAdjustsScrollViewInsets
為YES時,它會找view里的scrollView,并設(shè)置scrollView的contentInset為{64, 0, 0, 0}。如果你不想讓scrollView的內(nèi)容自動調(diào)整,將這個屬性設(shè)為NO(默認(rèn)值YES)。
當(dāng)我們在一個UIViewController中同時創(chuàng)建2個tableView的時候,如果把它們的frame中的Y坐標(biāo)設(shè)置為一樣,你可能會發(fā)現(xiàn)它們的位置并沒有達(dá)到你想要的結(jié)果.比如第一tableView個frame(0,0,320,568),另一個也frame(0,0,320,568),結(jié)果會發(fā)現(xiàn)第二個tableView的第一行數(shù)據(jù)被導(dǎo)航欄遮擋了,以至于我們不得已把第二個frame改成(0,64,320,568-64),雖然效果變成了我們想要的,但是卻不知道這是什么原因.......
其實(shí)這一切都是automaticallyAdjustsScrollViewInsets在作怪,我們可以先看一下官方文檔中對它的描述:
automaticallyAdjustsScrollViewInsets
Specifies whether or not the view controller should automatically adjust its scroll view insets.
@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
Discussion
Default value is?YES, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set toNO?if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.
Availability
- Available in iOS 7.0 and later.
Declared In
UIViewController.h
?
由此可見,當(dāng)我們一個界面有多個tableView之類的,要將它設(shè)置為NO,完全由自己手動來布局,就不會錯亂了.?
?
4、?addChildViewController
蘋果新的API增加了addChildViewController方法,并且希望我們在使用addSubview時,同時調(diào)用[self addChildViewController:child]方法將sub view對應(yīng)的viewController也加到當(dāng)前ViewController的管理中。對于那些當(dāng)前暫時不需要顯示的subview,只通過addChildViewController把subViewController加進(jìn)去。需要顯示時再調(diào)用transitionFromViewController:toViewController:duration:options:animations:completion方法。
另外,當(dāng)收到系統(tǒng)的Memory Warning的時候,系統(tǒng)也會自動把當(dāng)前沒有顯示的subview unload掉,以節(jié)省內(nèi)存。
?
- (BOOL)isViewLoaded?
判斷view是否已加載
?
?
?//Note that as of 5.0 this no longer will return the?presenting view controller.
返回父視圖控制器,5.0后不再返回模態(tài)框的視圖控制器
@property(nonatomic,readonly) UIViewController *parentViewController;
?
// 這個屬性被presentedViewController取代
@property(nonatomic,readonly) UIViewController *modalViewController NS_DEPRECATED_IOS(2_0, 6_0);
?
// The view controller that was presented by this view controller or its nearest ancestor.
返回被彈出的視圖控制器
@property(nonatomic,readonly) UIViewController *presentedViewController? NS_AVAILABLE_IOS(5_0);
?
// The view controller that presented this view controller (or its farthest ancestor.)
返回需要彈出的視圖控制器
@property(nonatomic,readonly) UIViewController *presentingViewController NS_AVAILABLE_IOS(5_0);
?當(dāng)我們在view controller A中模態(tài)顯示view controller B的時候,A就充當(dāng)presenting view controller(彈出VC),而B就是presented view controller(被彈出VC)。官方文檔建議這兩者之間通過delegate實(shí)現(xiàn)交互
?
?
@property(nonatomic,assign)?UIModalTransitionStyle?modalTransitionStyle
Modal Transition Style(彈出時的動畫風(fēng)格)
通過設(shè)置設(shè)置presented VC的modalTransitionStyle屬性,我們可以設(shè)置彈出presented VC時場景切換動畫的風(fēng)格,其定義如下:
typedef enum {UIModalTransitionStyleCoverVertical = 0,UIModalTransitionStyleFlipHorizontal,UIModalTransitionStyleCrossDissolve,UIModalTransitionStylePartialCurl, } UIModalTransitionStyle;我們可以看到有從底部滑入,水平翻轉(zhuǎn)進(jìn)入,交叉溶解以及翻頁這四種風(fēng)格可選。這四種風(fēng)格在不受設(shè)備的限制,即不管是iPhone還是iPad都會根據(jù)我們指定的風(fēng)格顯示轉(zhuǎn)場效果。
?
@property(nonatomic,assign) UIModalPresentationStyle modalPresentationStyle
Modal Presentation Styles(彈出風(fēng)格)
通過設(shè)置presented VC的modalPresentationStyle屬性,我們可以設(shè)置彈出View Controller時的風(fēng)格,有以下四種風(fēng)格,其定義如下:
typedef enum {UIModalPresentationFullScreen = 0,UIModalPresentationPageSheet,UIModalPresentationFormSheet,UIModalPresentationCurrentContext, } UIModalPresentationStyle;UIModalPresentationFullScreen代表彈出VC時,presented VC充滿全屏,如果彈出VC的wantsFullScreenLayout設(shè)置為YES的,則會填充到狀態(tài)欄下邊,否則不會填充到狀態(tài)欄之下。
UIModalPresentationPageSheet代表彈出是彈出VC時,presented VC的高度和當(dāng)前屏幕高度相同,寬度和豎屏模式下屏幕寬度相同,剩余未覆蓋區(qū)域?qū)儼挡⒆柚褂脩酎c(diǎn)擊,這種彈出模式下,豎屏?xí)r跟UIModalPresentationFullScreen的效果一樣,橫屏?xí)r候兩邊則會留下變暗的區(qū)域。
UIModalPresentationFormSheet這種模式下,presented VC的高度和寬度均會小于屏幕尺寸,presented VC居中顯示,四周留下變暗區(qū)域。
UIModalPresentationCurrentContext這種模式下,presented VC的彈出方式和presenting VC的父VC的方式相同。
這四種方式在iPad上面統(tǒng)統(tǒng)有效,但在iPhone和iPod touch上面系統(tǒng)始終已UIModalPresentationFullScreen模式顯示presented VC。
?
preferredContentSize
preferredContentSize在UIContentContainer協(xié)議中是只讀的,對應(yīng)的UIViewController有可寫的版本。我們可以使用preferredContentSize來設(shè)置我們期望的ChildViewController的界面大小。舉個例子,如果應(yīng)用中使用的popOver大小會發(fā)生變化,iOS7之前我們可以用contentSizeForViewInPopover來調(diào)整。iOS7開始這個API被廢棄,我們可以使用preferredContentSize來設(shè)置。
當(dāng)一個容器ViewController的ChildViewController的這個值改變時,UIKit會調(diào)用preferredContentSizeDidChangeForChildContentContainer這個方法告訴當(dāng)前容器ViewController。我們可以在這個方法里根據(jù)新的Size對界面進(jìn)行調(diào)整。
?
- (UIStatusBarStyle)preferredStatusBarStyle
在你自己的UIViewController里重寫此方法,返回你需要的值(UIStatusBarStyleDefault 或者 UIStatusBarStyleLightContent);
注意:
- 這里如果你只是簡單的return一個固定的值,那么該UIViewController顯示的時候,程序就會馬上調(diào)用該方法,來改變statusBar的前景部分;
- 如果在該UIViewController已經(jīng)在顯示在當(dāng)前,你可能還要在當(dāng)前頁面不時的更改statusBar的前景色,那么,你首先需要調(diào)用下面的setNeedsStatusBarAppearanceUpdate方法(這個方法會通知系統(tǒng)去調(diào)用當(dāng)前UIViewController的preferredStatusBarStyle方法), 這個和UIView的setNeedsDisplay原理差不多(調(diào)用UIView對象的setNeedsDisplay方法后,系統(tǒng)會在下次頁面刷新時,調(diào)用重繪該view,系統(tǒng)最快能1秒刷新60次頁面,具體要看程序設(shè)置)。
?
?
?
?
- (BOOL)prefersStatusBarHidden
//隱藏狀態(tài)欄
IOS7中,不僅應(yīng)用的風(fēng)格有一定的變化,狀態(tài)欄變化比較大,我們可以看到UIVIEWCONTROLLER的狀態(tài)欄與導(dǎo)航欄基本是一體的。因此UIVIEWCONTROLLER的HIDE/SHOW狀態(tài)的方法也跟其他版本的不一樣了。 在IOS7以前的版本,HIDE/SHOW是通過以下代碼實(shí)現(xiàn)
[[UIApplication?sharedApplication]?setStatusBarHidden:YES(NO)?withAnimation:UIStatusBarAnimationSlide]; ?
在iOS7中默認(rèn)情況下,這個方法不成功了。到setStatusBarHidden:withAnimation:聲明的頭文件去看看,多了一句注釋: // Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system. 現(xiàn)在在iOS7中,status bar的外觀默認(rèn)依賴UIViewController, 也就是說status bar隨UIViewController的不同而不同。在這種默認(rèn)的方式下,用全局的方法setStatusBarHidden:withAnimation:是行不通的。
google一下發(fā)現(xiàn)現(xiàn)在的解決方法有兩種:
如果只是單純的隱藏狀態(tài)欄,那么是在默認(rèn)情況下,只需要重新實(shí)現(xiàn)兩個新方法
上面一個回調(diào)方法返回status bar顯示時候的樣式,下面一個回調(diào)控制是否顯示status bar.
調(diào)用下面的一行代碼將會觸發(fā)上面的回調(diào)
[self?setNeedsStatusBarAppearanceUpdate];??
?
如果想在hiden/show之間有點(diǎn)動畫效果,用下面的代碼即可:
或者調(diào)用下面的代碼:
?
?
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
現(xiàn)在有兩種動畫效果:UIStatusBarAnimationFade ,UIStatusBarAnimationSlide.從他們的名字可以得知他的具體是什么眼的效果。 實(shí)現(xiàn)動畫需要重載:
| 1 2 3 4 | - (UIStatusBarAnimation )preferredStatusBarUpdateAnimation { ????return UIStatusBarAnimationSlide; } |
?但是重載這個方法后,并沒有動畫效果。這時,我們需要把 [self setNeedsStatusBarAppearanceUpdate] 放在動畫block中執(zhí)行:
| 1 2 3 4 | [UIView animateWithDuration:0.3 ?????????????????animations:^{ ????????????????????[self setNeedsStatusBarAppearanceUpdate]; }]; |
這樣動畫效果就出現(xiàn)了。
?
// This should be called whenever the return values for the view controller's status bar attributes have changed. If it is called from within an animation block, the changes will be animated along with the rest of the animation block.
- (void)setNeedsStatusBarAppearanceUpdate
//每當(dāng)statusbar的屬性改變的時候,這個函數(shù)就應(yīng)該被調(diào)用,更新這個狀態(tài)。如果在動畫的block中調(diào)用,就會有動畫效果。
?
?
// An array of children view controllers. This array does not include any presented view controllers.
保存子視圖控制器的數(shù)組
@property(nonatomic,readonly) NSArray *childViewControllers NS_AVAILABLE_IOS(5_0);
?
蘋果新的API增加了addChildViewController方法,并且希望我們在使用addSubview時,同時調(diào)用[self addChildViewController:child]方法將sub view對應(yīng)的viewController也加到當(dāng)前ViewController的管理中。對于那些當(dāng)前暫時不需要顯示的subview,
只通過addChildViewController把subViewController加進(jìn)去。需要顯示時再調(diào)用transitionFromViewController:toViewController:duration:options:animations:completion方法。
?
//添加、移除子控制器
- (void)addChildViewController:(UIViewController *)childController
- (void) removeFromParentViewController
?
?
- (UIViewController *)childViewControllerForStatusBarStyle NS_AVAILABLE_IOS(7_0);
這個接口也很重要,默認(rèn)返回值為nil。當(dāng)我們調(diào)用setNeedsStatusBarAppearanceUpdate時,系統(tǒng)會調(diào)用application.window的rootViewController的preferredStatusBarStyle方法,我們的程序里一般都是用UINavigationController做root,如果是這種情況,那我們自己的UIViewController里的preferredStatusBarStyle根本不會被調(diào)用;?
這種情況下childViewControllerForStatusBarStyle就派上用場了,?
我們要子類化一個UINavigationController,在這個子類里面重寫childViewControllerForStatusBarStyle方法,如下:
上面代碼的意思就是說,不要調(diào)用我自己(就是UINavigationController)的preferredStatusBarStyle方法,而是去調(diào)用navigationController.topViewController的preferredStatusBarStyle方法,這樣寫的話,就能保證當(dāng)前顯示的UIViewController的preferredStatusBarStyle方法能影響statusBar的前景部分。
另外,有時我們的當(dāng)前顯示的UIViewController可能有多個childViewController,重寫當(dāng)前UIViewController的childViewControllerForStatusBarStyle方法,讓childViewController的preferredStatusBarStyle生效(當(dāng)前UIViewController的preferredStatusBarStyle就不會被調(diào)用了)。
簡單來說,只要UIViewController重寫的的childViewControllerForStatusBarStyle方法返回值不是nil,那么,UIViewController的preferredStatusBarStyle方法就不會被系統(tǒng)調(diào)用,系統(tǒng)會調(diào)用childViewControllerForStatusBarStyle方法返回的UIViewController的preferredStatusBarStyle方法。
- (void)setNeedsStatusBarAppearanceUpdate:
讓系統(tǒng)去調(diào)用application.window的rootViewController的preferredStatusBarStyle方法,如果rootViewController的childViewControllerForStatusBarStyle返回值不為nil,則參考上面的講解。
?
?
-?(void)loadViewIfNeeded?NS_AVAILABLE_IOS(9_0);
使用如下代碼進(jìn)行UIViewController之間的跳轉(zhuǎn):
?TestViewController *testViewController = [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil];
?//[testViewController loadViewIfNeeded];
?testViewController.imageViewCourse.image = image;
testViewController.lbCourse.text = course;
?[self presentViewController:testViewController animated:YES completion:nil];
我們使用nib來加載一個TestViewController并對其屬性賦值, 然后跳轉(zhuǎn)。問題在于執(zhí)行完initWithNibName之后,testViewController.imageViewCourse和testViewController.lbCourse都為nil, 則表現(xiàn)出來的是跳轉(zhuǎn)到TestViewController之后, 其中的imageViewCourse和lbCourse中沒有內(nèi)容。
我們知道,當(dāng)我們從StoryBoard中加載ViewController時,我們在Controller中拖拽的視圖是可以被初始化的,這里面有一點(diǎn)需要我們注意,如果我們需要向controller中視圖進(jìn)行傳值設(shè)置,通過以下方法得到的Controller中,視圖還沒有被初始化創(chuàng)建出來,可以想象,如果我們這時候需要對label進(jìn)行一些屬性設(shè)置,必然失敗。有人提出可以在創(chuàng)建后,手動調(diào)以下loadView方法,我們試一下,結(jié)果如下:可以看到,手動調(diào)用loadView后,label是被創(chuàng)建了出來,但是暴漏了一個更嚴(yán)重的問題,系統(tǒng)不在調(diào)用ViewDidLoad方法,這是十分有風(fēng)險的,因?yàn)槲覀兇蟛糠值某跏蓟a都會放在這個方法里,所以手動調(diào)用loadView是一種錯誤的方法,apple文檔聲明對于loadView方法,我們從來都不要手動直接調(diào)用,那么我們?nèi)绾螌?shí)現(xiàn)創(chuàng)建后對成員對象進(jìn)行傳值設(shè)置呢,iOS9中增加了這樣一個方法:loadViewIfNeeded
這個方法十分有用,調(diào)用這個方法,會將視圖創(chuàng)建出來,并且不會忽略viewDidLoad的調(diào)用。
在iOS9中,UIViewController還增加了下面一個布爾值的屬性,可以同來判斷controller的view是否已經(jīng)加載完成:
@property(nullable,?nonatomic,?readonly,?strong)?UIView?*viewIfLoaded?NS_AVAILABLE_IOS(9_0);
?
posted on 2015-07-29 17:44 城之內(nèi) 閱讀(...) 評論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/HypeCheng/p/4686645.html
總結(jié)
以上是生活随笔為你收集整理的ViewController类中得方法和属性的用途的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: form表单按enter键自动提交的问题
- 下一篇: userdel account is c