load view
unload view
相关方法
@property(null_resettable, nonatomic,strong) UIView *view; // The getter first invokes [self loadView] if the view hasn't been set yet. Subclasses must call super if they override the setter or getter.
- (BOOL)isViewLoaded NS_AVAILABLE_IOS(3_0);
- (void)loadView; // This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.
- (void)loadViewIfNeeded NS_AVAILABLE_IOS(9_0); // Loads the view controller's view if it has not already been set.
@property(nullable, nonatomic, readonly, strong) UIView *viewIfLoaded NS_AVAILABLE_IOS(9_0); // Returns the view controller's view if loaded, nil if not.
@property(nullable, nonatomic,copy) NSString *title; // Localized title for use by a parent controller.
/* The preferredContentSize is used for any container laying out a child view controller.
*/
@property (nonatomic) CGSize preferredContentSize NS_AVAILABLE_IOS(7_0);
@property(nullable, nonatomic, readonly, copy) NSString *nibName; // The name of the nib to be loaded to instantiate the view.
@property(nullable, nonatomic, readonly, strong) NSBundle *nibBundle; // The bundle from which to load the nib.
@property(nullable, nonatomic, readonly, strong) UIStoryboard *storyboard NS_AVAILABLE_IOS(5_0);
解释:
- view:UIViewController的view hierarchy,如果访问property view getter时值为nil,会自动调用loadView,view应该为UIViewcontroller独享,不应共享
- isViewLoaded返回view是否为nil,如果值为nil,也不会自动调用loadView
loadView
loadView负责view hierarchy加载(加载nib,storyboard)或创建(代码创建),如果访问property view getter时值为nil,会自动调用loadView
加载逻辑:
- loadView优先从bundle(nibBundle为nil表示main bundle,即app本身)加载nib(nibName)
- 如果nibName不为nil,如果加载成功(bundle中存在nib),通过initWithCoder实例化view hierarchy,如果加载失败(bundle中不存在nib),crash
- 如果nibName为nil,尝试加载nib(nib文件名为UIViewController class name),如果加载成功(bundle中存在nib),通过initWithCoder实例化view hierarchy,如果加载失败(bundle中不存在文件名为UIViewController class name的nib),通过initWithFrame实例化view hierarchy
- 通过initWithFrame实例化view hierarchy时,view.frame初始化为与设备屏幕重叠,即frame.origin为(0, 0),frame.size为设备逻辑尺寸(逻辑点),在viewWillAppear中view.frame设置为window.bounds(此时view hierarchy还没加入window,但window可通过UIApplication获取)
代码逻辑:
@implementation UIViewController
//...
- (void)loadView
{
if(nibName)
{
if(nib exist in nibBundle) //nib名为nibName
{
self.view = load from nib;
}
else
{
crash;
}
}
else
{
if(nib exist in nibBundle) //nib名为NSStringFromClass([self class])
{
self.view = load from nib;
}
else
{
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
}
}
//...
@end