使用IB
描述控制器view
并用代码加载的时候,内部实现逻辑是怎样的?
我们新建一个控制器,控制器view
用IB
描述。
场景搭建
1 | // LoginViewController.h |
创建View.xib
的时候,我们一般选择View
模板
示例一(TestView.xib
)
条件:创建一个名称为TestView
的IB
,用来描述控制器view
加载:
1 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
效果:
把加载方式修改下:initWithNibName:
传nil
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:nil bundle:nil]; |
修改后的效果:
示例二(Login.xib
)
条件:创建一个名称为Login
的IB
,用来描述控制器view
加载:
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:@"Login" bundle:nil]; |
效果:
把加载方式修改下:initWithNibName:
传nil
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:nil bundle:nil]; |
修改后的效果:
示例三(LoginView.xib
)
条件:创建一个名称为LoginView
的IB
,用来描述控制器view
加载:
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil]; |
效果:
把加载方式修改下:initWithNibName:
传nil
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:nil bundle:nil]; |
修改后的效果:
示例四(LoginViewController.xib
)
条件:创建一个名称为LoginViewController
的IB
,用来描述控制器view
加载:
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil]; |
效果:
把加载方式修改下:initWithNibName:
传nil
1 | LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:nil bundle:nil]; |
修改后的效果:
扩展
在此基础上如果使用以下代码创建控制器,会默认加载和控制器同名的IB
。
1 | LoginViewController *loginVC = [[LoginViewController alloc] init]; |
为什么呢?我们重写LoginViewController
的initWithNibName:bundle:
方法看下。
1 | @implementation LoginViewController |
通过输入我们可以看到,即使用init
进行初始化,也会进入到initWithNibName:bundle:
方法,只不过传入的nibName
是空。
总结
如果initWithNibName:
指定了IB
名称,则按照指定的名称去查找对应的IB
文件。如果是nil
,则有两种情况:
iOS9
之前- 优先加载控制器同名且去除
Controller
的IB
文件,再去加载控制器同名的IB
。 - 例:优先查找
LoginView.xib
,当不存在时,再查找LoginViewController.xib
,如果最终没有找到,则不使用IB
。
- 优先加载控制器同名且去除
iOS9
之后- 优先加载控制器同名的
IB
,再去加载去除Controller
的IB
文件。 - 例:优先查找
LoginViewController.xib
,当不存在时,再查找LoginView.xib
,如果最终没有找到,则不使用IB
。
- 优先加载控制器同名的