- iPhone UIKit详解
- 王志刚 王中元 朱蕾编著
- 2037字
- 2020-08-28 08:00:21
1.3 不使用Interface Builder的Hello World程序
上一节我们使用Interface Builder工具创建完成了Hello World应用程序,前一节我们已经介绍过了,我们创建这个Hello World应用程序的主要目的是了解UIkit框架中控件类(如UITableView等)的使用方法,其实Interface Builder中制作界面时使用的就是UIkit框架中的控件类,只不过是使用一种所见即所得的方式来完成界面的设计,另外Interface Builder中还有其他外面看不到的处理。
不可否认Interface Builder是一款设计得非常完美的开发工具,使用起来也非常方便。但是我们如果想更深入理解UIKit框架及其中的控件类的话,最好还是撇开Interface Builder,采取直接编写代码的方式来进行开发,我们可以从中了解到那些由Interface Builder完成的,被隐藏起来的工作,最后真正理解UIKit框架的工作原理,有助于完成更复杂iPhone应用程序的设计。
而本节将讲解如何将上面的Hello World工程改造成不使用Interface Builder的工程,其实就是去掉了工程中的xib文件,而直接编写控件代码。今后就可以利用这个工程测试各种UIkit框架中的控件类。
1.3.1 编辑HelloWorldAppDelegate.m
为了实现去掉HelloWorld工程中的MainWindow.xib文件,我们首先要重新编辑HelloWorldAppDelegate.m文件,将MainWindow.xib中完成的工作转移到HelloWorldApp Delegate.m中完成。
在代码编辑窗口双击HelloWorldAppDelegate.m文件,编辑HelloWorldApp Delegate.m application:didFinishLaunchingWithOptions方法,其他的只有框架的方法可以删除掉,如果保留也没有什么问题。方法application:didFinishLaunchingWithOptions中追加的代码如下。
-(void)applicationDidFinishLaunching:(UIApplication *)application { // 取得与应用程序窗口相同大小的矩形 CGRect rect = [window frame]; // 创建UILabel的实例,并初始化 // 生成与应用窗口大小相同的UILabel UILabel* label = [[UILabel alloc] initWithFrame:rect]; // 在UILabel中显示信息为“Hello,world!” label.text = @"Hello,world!"; // 将创建完成的UILabel追加到Window中 [window addSubview:label]; // 最后请不要忘记了执行release [label release]; // Override point for customization after application launch [window makeKeyAndVisible]; }
代码追加在application:didFinishLaunchingWithOptions方法中事先已有调用makeKeyAndVisible方法的代码前。
上述新追加的代码大致依次完成如下的工作。
- UILabel对象的创建以及初始化。
- 向UILabel对象设置“Hello World!”信息。
- 将UILabel对象加入到Window(窗口)中。
UILabel是创建标签的类。UILabel创建完成后,使用initWithFrame:方法进行初始化。在initWithFrame:方法的参数中需要指定具体的位置以及大小,这里为了方便,将其指定为与应用程序的窗口(Window)相同的位置及大小。Window的frame属性中保存了窗口的位置及大小,将这个frame属性直接传入到initWithFrame:方法的参数中是最简便的。
UILabel的初始化完成后,接着就是将UILabel对象的text属性设置为“Hello World!”,最后使用addSubview:方法将UILabel对象追加到Window中。我们从第1.1节看到Window对象的类UIWindow是UIView的子类,而UILabel也是UIView的子类。addSubview:方法正是在UIView类中定义的方法,负责将UIView对象追加到其他UIView对象中。
最后,不要忘记了对追加完成的UILabel对象执行release,这是实现参照统计式内存管理的需要。
1.3.2 删除MainWindow.xib文件
我们只有将MainWindow.xib文件删除了之后,才可以说告别了Interface Builder。
选择“Groups & Files”最上层的HelloWorld,Xcode的中央窗口会显示工程包含的所有文件及框架(见图1-12)。选中MainWindow.xib文件,单击鼠标右键,选择“delete”命令后,在对话框中单击“Also Move to Trash”按钮(见图1-13),即可将MainWindow.xib文件物理删除。
光进行上述的物理删除动作,还不能说完全删除了MainWindow.xib文件的残余,我们还必须编辑info.plist文件。双击图1-12窗口中的HelloWorld-info.plist文件,我们可以发现在info.plist文件的编辑窗口(见图1-14)的最后有key名为“Main nib file base name”的项目,单击鼠标右键,在弹出的快捷菜单中选择“cut”命令,即可将此项删除。这样与MainWindow.xib文件相关的所有信息都被删除干净了。
图1-12 删除MainWindow.xib文件
图1-13 单击“Also Move to Trash”按钮
图1-14 编辑info.plist文件
1.3.3 编辑main.m文件
删除了MainWindow.xib文件,算是彻底删除创建窗口的处理了。我们要复活创建窗口的处理,首先要编辑main.m文件。双击图1-12所示窗口中的main.m文件,打开编辑窗口。将其中调用UIApplicationMain函数的行修改成如下代码所示。
// 原代码 // int retVal = UIApplicationMain(argc,argv,nil,nil); // 只修改第4个参数 int retVal = UIApplicationMain(argc,argv,nil,@"HelloWorld AppDelegate");
这样的修改,是将原来自动设置的应用程序委托(本例为HelloWorldAppDelegate,所谓应用程序委托,是当应用程序状态变化时接收通知的对象,为继承了UIApplicationDelegate协议类的实例),在此明确指定它罢了。UIApplicationMain函数的第4个参数正是用于指定应用程序委托的参数。如果此参数为nil,会根据info.plist文件中设置的nib或者xib文件,自动决定应用程序委托。因为前面已经删除了xib文件,在此必须指定字符串“HelloWorldAppDelegate”代表的类名,来决定应用程序委托。
1.3.4 再次编辑HelloWorldAppDelegate.m文件
编辑完了main.m,还不能够正常编译整个HelloWorld工程,在HelloWorldAppDelegate.m文件中,有编程经验的读者可能注意到,Window实例变量还没有被初始化。因此还必须再编辑一下HelloWorldAppDelegate.m文件完成Window实例变量的初始化动作。
需要在application:didFinishLaunchingWithOptions:方法的最上部追加如下初始化Window实例变量的代码。
// 自己创建Window对象 CGRect bounds = [[UIScreen mainScreen] bounds]; window = [[UIWindow alloc] initWithFrame:bounds];
上述代码正是将以前由MainWindow.xib自动创建的窗口(UIWindow)实例,在此自己手动创建的代码。
UIWindow实例的创建不是一件很难的事情,先调用alloc方法生成UIWindow的实例,然后调用initWithFrame方法对其进行初始化。此处,需要取出UIScreen类的bounds属性作为画面的大小,并以参数的形式传入。
最后还有一个工作需要完成,那就是删除HelloWorldAppDelegate.m文件中的IBOutlet关键字。实际上如果不删除,应用程序也不会有任何问题,IBOutlet关键字是Interface Builder识别插座变量的标志,留在程序中也没有任何意义。
到此为止,我们已清除了所有与Interface Builder相关的内容,下面可以测试一下应用程序的执行结果,单击Xcode窗口上部的“Build and Debug”按钮,编译建立完成后,显示如图1-15所示的画面。如果想让字符串“Hello World!”居中显示,可以修改相关属性,有兴趣的读者可自行完成。
图1-15 HelloWorld结果画面