UIViewController官方解析

本文详细解析UIViewController的生命周期,包括viewDidLoad、viewDidUnload、modalTransitionStyle、modalPresentationStyle等关键方法的作用,以及如何处理内存警告、视图加载与初始化、显示与隐藏的回调。同时探讨了如何在不同场景下正确使用UIViewController的子类和视图操作。

viewdidunload:

这个方法在什么时刻调用呢?

非英语国家的人往往会认为是在view被摧毁的时刻调用,事实上不然,这个方法只会在内存报警的时刻调用。这里还有一点要注意的时,当出现内存警告的时候,是调用正在显示的视图控制器的父视图控制器的viewdidUnload方法,而不是正在显示的视图控制器的viewDidUnload方法。因为如果调用了正在显示的视图控制器的viewDidUnload方法,那么用户正在看的界面就会消失,虽然释放了内存但是用户显然没法接受,自然要释放该视图下面看不到的视图控制器中的视图。被释放的视图,下次加载的时候再调用viewDidLoad的方法,所以ViewDidUnload的方法是和viewDidload方法相互对应的。


需要注意的是:

UIviewController的初始化过程不同于UIView,UIviewController在没有调用其涉及到UI显示的属性(背景颜色等)或者没有即将显示之前不会对其内部的View进行初始化,也就是说,alloc和init能够初始化这个ViewController但是却没有初始化其中的View,此时根本不会调用ViewDidLoad方法和loadView方法。)即便是自定义了loadView也是一样的

首先是:

1:模态的ViewController(能够中断正常程序流程):

attention:UIModalTransitionStyle只有在Ipad下才能使用所有。其他设备都是默认的全屏UIModalPresentationFullScreen

动画效果则不受设备限制!

UIModalTransitionStyle与

UIModalPresentationStyle

很明显:这个两个代表动画类型的枚举!哪里用到了他们呢?

@property(nonatomic,assign) UIModalTransitionStyle modalTransitionStyleNS_AVAILABLE_IOS(3_0);

@property(nonatomic,assign) UIModalPresentationStyle modalPresentationStyleNS_AVAILABLE_IOS(3_2);

UIModalTransitionStyle用来设置动画效果

--------------是什么时刻的效果呢?--------

参考:http://www.cnblogs.com/smileEvday/archive/2012/05/29/presentModalViewController.html

在一个ViewController中显示另外一个ViewController,也就是说在A中使用

presentViewController弹出B的时刻,modalPresentationStyle决定的是B的显示类型,使用B.modalPresentationStyle,和在横屏和竖屏的不同情况下的B的显示状态,可以定制其大小等(还记得那些模态的弹窗么?除了显示的部分,屏幕其他部分都会变暗并不能被点击。)。

UIModalTransitionStyle也就是设置在A->B切换的过程的切换动画。

----------------------

将B设置成

UIModalTransitionStylePartialCurl时的效果:(红色为A,此时不能点击。蓝色块为B,这里我修改了B 的位置)


2:构造函数:

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

官方要求:

自定义UIViewController的子类时,要求继承这个构造函数,就算没有nib,也会使用这个方法进行初始化。但是为了方便,默认的构造函数init也会调用这个构造函数。

对这个方法的简介是:

If you invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose name is the same as your view controller's class. If no such NIB in fact exists then you must either call -setView: before -view is invoked, or override the -loadView method to set up your views programatically.

意思大概是:

如果使用这个构造函数的时刻没有传参,那么就会调用loadView方法(loadView方法没被子类覆写)去寻找当前目录下的与类名相同的nib文件。如果loadview也没有找到的话,就会放弃从nib文件初始化。(只要loadView没被覆写,就算再初始化时刻没有传参,有nib类名与controller名称相同的前提下,也是能够加载nib的)


而如果覆写了loadView,nib就不会再生效了,因为他们在完全不同的两条初始化路程上。


从官方给我们的文件可以解读出:

viewController在初始化其View的时刻,是根据loadView方法有没有被覆写来判断的,如果被覆写了,那么就会直接用这个方法对其View进行初始化。

只有在没有被覆写的前提下,才会利用故事板进行初始化。

-------------

无论哪一种初始化方式,都会在初始化完成之后执行ViewDidLoad方法。

3:关于ViewController的View

viewController实际意义上就是一个UIView的容器,其中天生自带一个View用于显示内容。这个View的坐标是不记算状态栏的整个屏幕的大小,也就是320*460(iphone4),起始坐标就是除去状态栏之后的屏幕左上角。loadView方法也就是对这个View的初始化过程,一定会执行,只不过如果被覆写了就执行子类方法,不覆写就会执行系统默认的内容。

- (void)viewWillUnloadNS_DEPRECATED_IOS(5_0,6_0);

- (void)viewDidUnloadNS_DEPRECATED_IOS(3_0,6_0);// Called after the view controller's view is released and set to nil. For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc.

- (void)viewDidLoad;// Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers unarchived from a nib, this is after the view is set.

- (BOOL)isViewLoadedNS_AVAILABLE_IOS(3_0);

这些方法也是对VIewController的View的load状态的监听方法。


- (void)viewWillAppear:(BOOL)animated;   // Called when the view is about to made visible. Default does nothing

- (void)viewDidAppear:(BOOL)animated;    // Called when the view has been fully transitioned onto the screen. Default does nothing

下面的方法在View被覆盖的时刻也会调用。

- (void)viewWillDisappear:(BOOL)animated;// Called when the view is dismissed, covered or otherwise hidden. Default does nothing

- (void)viewDidDisappear:(BOOL)animated; // Called after the view was dismissed, covered or otherwise hidden. Default does nothing

这些方法是对View的出现和消失做的监听。

- (void)viewWillLayoutSubviewsNS_AVAILABLE_IOS(5_0);

// Called just after the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. The default is a nop.

- (void)viewDidLayoutSubviewsNS_AVAILABLE_IOS(5_0);

在view对加载到其中的子View进行布局时刻调用。


// The view controller that was presented by this view controller or its nearest ancestor.

@property(nonatomic,readonly) UIViewController *presentedViewController NS_AVAILABLE_IOS(5_0);

被这个容器present出来的容器

// The view controller that presented this view controller (or its farthest ancestor.)

@property(nonatomic,readonly) UIViewController *presentingViewControllerNS_AVAILABLE_IOS(5_0);

把这个容器present出来的容器


/*

  These four methods can be used in a view controller's appearance callbacks to determine if it is being

  presented, dismissed, or added or removed as a child view controller. For example, a view controller can

  check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:

  method by checking the expression ([self isDismissing] || [self isMovingFromParentViewController]).

*/

翻译:

下面的四个方法是在一个ViewController出现下列变化的时刻调用的,根据这个Controller是被推出,移除或者是作为一个子的ViewController添加到父类的ViewController中去 还是从父ViewController中移除的时刻。

例如:一个ViewController能够通过检查自身的两个方法isDismissing和isMovingFromParentViewController来确定当自身在消失的时刻是被父ViewController弹出(pop),还是被dismiss掉的。

- (BOOL)isBeingPresentedNS_AVAILABLE_IOS(5_0);

- (BOOL)isBeingDismissedNS_AVAILABLE_IOS(5_0);

- (BOOL)isMovingToParentViewControllerNS_AVAILABLE_IOS(5_0);

- (BOOL)isMovingFromParentViewControllerNS_AVAILABLE_IOS(5_0);


wantsFullScreenLayout

设置为true的话,那么状态栏的高度将不再计算到内,也就是说,view的高度变成320*480;


- (void)setEditing:(BOOL)editing animated:(BOOL)animated;// Updates the appearance of the Edit|Done button item as necessary. Clients who override it must call super first.

编辑状态为no的话,键盘会落下。


- (UIBarButtonItem *)editButtonItem;// Return an Edit|Done button that can be used as a navigation item's custom view. Default action toggles the editing state with animation.

返回一个和当前ViewController状态相关的能放置到UInavigationBar上的ButtonItem,点击按钮可以切换当前状态。


@property(nonatomic,readonly) NSArray *childViewControllersNS_AVAILABLE_IOS(5_0);

当前ViewController的子ViewController数组。

- (void)addChildViewController:(UIViewController *)childControllerNS_AVAILABLE_IOS(5_0);

- (void) removeFromParentViewControllerNS_AVAILABLE_IOS(5_0);

对这个数组进行管理。

- (void)willMoveToParentViewController:(UIViewController *)parentNS_AVAILABLE_IOS(5_0);

- (void)didMoveToParentViewController:(UIViewController *)parentNS_AVAILABLE_IOS(5_0);

这些方法会在被添加的时刻触发

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

实现对子ViewController的动画切换。

参考:

http://w11h22j33.iteye.com/blog/1565208 获得更加详细内容。

大致意思:

当前的ViewController不会因为添加了子ViewController而发生改变,不会像导航那样,自动显示ViewControllers中下标最大的ViewController。

只有当执行 addsubview:(子ViewController.view)把子控制器的视图加到某个UIview中的时刻,子ViewController的View才会显示。(但是childViewControllers中的ViewController只需要有一个的view添加即可)

首先是需要一个层,然后才能对这个层进行变换。

然后使用动画切换的方法,可以实现这个被添加到当前ViewController中的View的内容的改变。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值