【原创】第一个iOS应用程序

万事开头难。斗霜傲雪二十年,堂堂剑气尚寒。——《诗词三百首》

全文概览

第一章 窗口与应用程序

在iOS应用程序中窗口(Window)是视图(View)的载体,每一个应用程序都至少有一个Window,一般而言也只有一个Window,在某些特定应用中会出现多个Window,本文暂不考虑多窗口的情况。Window是UIWindow类的一个实例,当应用程序启动时会创建这个窗口。当窗口显示出来后,一般来说,开发者就很少再会用到窗口。

在“iOS开发入门教程”一文中已经描述过创建一个iOS引用程序的过程,这里不做重复。根据iOS应用程序的生命周期可以发现,每一个iOS应用程序启动的时候都会调用一个启动方法:

1
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

下面我们就从这里开始,完成第一个iOS应用程序。

方法全貌如图:

启动方法

我们先看方法实现的开始和结束有这样两行代码:

1
2
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];

首先说明一下这两行代码各自的功能,第一行:以屏幕尺寸为标准初始化一个UIWindow对象的实例。第二行:设置实例为主窗口并显示。这样当应用程序启动后就能看到这个窗口了。回头再看看,self.window从何而来的呢?我们继续追踪。在“iOS开发入门教程”一文中我们讲过,iOS应用程序的入口是AppDelegate.m,它的头文件对应为AppDelegate.h,我们打开这个头文件,其内容如下:

AppDelegate

原来它(self.window)来自这里。此外不难发现,还声明了一个ViewController的实例viewController

第二章 添加视图

2.1 从nib文件初始化视图

再回到上面方法的实现中我们看还剩下下面两行代码:

1
2
self.viewController = [[ViewController alloc] initWithNibName: @"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;

ViewController是创建应用时生成的一个视图控制器(类),我们在结构中可以看到:

项目结构

显然self.viewController就是这个控制器的一个实例,而initWithNibName方法,顾名思义就是从指定名称的nib文件中初始化这个实例,特别说明:在早期的Xcode中xib本应是nib,后来更名为xib,因此,此处所指的nib即是xib文件。下面一行即为设置主视图控制器为ViewController的实例。个人理解这里的设置就相当于网站开发中设置网站的主页。

下面我们添加一点东西,验证一下,打开xib文件,单击视图,让视图处于焦点状态,右侧选中属性设置面板如图设置视图背景颜色:

设置背景颜色

点击Xcode左上角Run按钮或者Command + R快捷键,运行程序,效果如图:

背景设置预览

由此证明,我们从xib文件加载的应用程序视图已经成功了。

2.2 使用脚本添加视图

上一节已经跟大家掩饰了如何使用xib文件创建视图,但是显然强大的iOS开发不可能只有这么一种实现方式,下面我们就看下仅仅使用代码,如何实现上述效果。

首先,上一节中操作只修改了xib文件,并未对ViewController类进行设置,这里我们也不做修改,只需改变启动函数中的一部分代码并添加少许代码即可。

然后,我们修改启动函数如图:

代码设置视图

此时我们再次运行应用程序,会得到和上一节一样的效果。修改后的三行代码也很好理解:

  • 第一行,初始化一个空的视图控制器;
  • 第二行,设置视图控制器控制视图的位置和尺寸;
  • 第三行,设置视图的背景颜色为蓝色。
    应该说代码实现更符合程序员的逻辑。

第三章 添加子视图

3.1 通过xib添加子视图(subview)

首先简单介绍一下Xcode中控件的位置。记得在“iOS开发入门教程”一文中我提到过Xcode大致分为左中右三块区域,而右侧主要显示属性和控件信息,如图所示:

控件区

将UIButton拖一个到视图上,效果如图:

添加UIButton

可拖动周围的小方块调整按钮尺寸,也可拖动整个按钮调整位置,双击文字区可以修改文本。

小技巧:当拖动改变尺寸的同时按住alt(Option)键,可显示四边边距。

接着我们点击Xcode左上角的Run按钮运行应用,效果如图:

预览

使用xib添加控件,就是这么简单。

3.2 通过代码实现添加子视图

虽然Xcode提供了如此方便的视图添加方式,但是在实际开发中往往会遇到一些用可视化工具无法达到目的的情况,因此掌握使用代码添加视图,也是开发者必备的技能。

在上一章中,我们演示了使用代码添加视图控制器的方法。现在我们看一下ViewController类中的内容:

viewController

实际上当视图控制器创建成功并添加视图到Window后,视图控制器的- (void) viewDidLoad方法便会被触发,因此我们可以在viewDidLoad方法中用代码添加子视图。同上,我们还是在主视图中添加一个按钮,我们看下如何实现:

用代码添加子视图

此例中我们首先在@interface中定义了一个UIButtton类的实例btn,然后在viewDidLoad中实例化并设置其大小和位置,以及背景颜色和文本颜色,最后调用view的addSubview方法将btn添加到视图中。

特别注意:假如在创建项目的时候勾选了启用arc,那么这段代码没有问题。如果未选择启用arc,则应该在self.btn使用完毕后调用[self.btn release];释放内存,避免内存泄露。

现在我们运行应用程序得到如下效果:

代码添加的按钮预览

好了,两种添加视图的方法都实现了,慢慢消化一下。

第四章 控件与事件

4.1 通过代码获取视图中的控件

如果是通过代码实例化的控件,则理所当然的与代码关联了,可在代码中直接使用对应的变量名调用,如上一节中创建的btn实例,则可以直接调用[self.btn setTitle:forState:]方法。而直接拖到nib文件中的控件,我们却没有办法直接使用,那么如何能够取到nib中的控件呢?

其实很简单,Xcode提供了一个强大的nib编辑器Interface Builder,似乎简称IB。打开nib文件后,选择Xcode编辑区的Assistant Editor此时代码编辑区会出现左右两个并排的代码区,这时我们让两个区域分别显示nib文件和视图控制器的头文件,如图所示:

Assistant Editor

此时按住Mac键盘的control键,然后用鼠标将控件拖动到@interface@end之间的区域,如图:

关联视图

填写好实例名称之后,其他选项默认即可,点击Connect便关联成功了,此时在代码去会自动生成下面这行代码:

1
@property (weak, nonatomic) IBOutlet UIButton *btn;

并且左侧行号区会出现一个实心的圆圈。之后我们便可以在.m文件中控制这个控件了,比如添加事件,当用户点击这个按钮的时候给出响应等。

另外一种关联的方式,大同小异。首先在头文件中定义实例变量,比如:

1
@property (strong, nonatomic) IBOutlet UIButton *btn;

此时,其左侧行号区出现空心圆圈。然后保存文件,切换回nib视图,此时在File's Owner上鼠标右键出现一个窗口,如图:

关联视图

你会发现刚才定义的实例变量出现在了上图红框位置,然后使用鼠标拖动对应变量右侧的空心圆到对应的控件上,松开鼠标,此时注意复层中已经出现了关联关系,至此关联成功。再返回头文件查看,发现此时变量左侧的空心圆也变成实心的了。

4.2 给控件添加事件

上一节已经讲过如果将控件与代码关联,关联好后我们就可以给控件绑定相应的事件,让之拥有最终与用户发生交互的能力。那么如何让一个控件拥有自己的事件呢?且继续往下看。

给控件绑定事件有多种方法,第一种,使用纯代码实现:

1
[self.btn addTarget:self action:@selector(doSomething) forControlEvents:UIControlEventTouchUpInside];

然后我们实现一下doSomething方法:

1
2
3
4
5
6
7
8
- (void) doSomething {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Test"
message:@"This is an Alert Information"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles: nil];
[alert show];
}

这样设置之后,当用户在按钮内部点击并松开手指时,就会触发TouchUpInside事件,调用doSomething方法。结果如图:

AlertView

第二种,这种方法与创建代码与控件关联相类似。首先打开Assistant Editor,打开头文件和nib文件,按住control键拖动空控件到控制器类的中间,如图:

delegateEvent

注意红框部分与创建关联时有所不同,还要注意填写Name时,如果时较早版本的Xcode,需要在名称后面添加:。点击Connect按钮,会自动生成这样一句代码:

1
- (IBAction)doSomething:(id)sender;

好了,事件又一次绑定成功了!Command + R运行应用,查看效果。

4.3 补充获取控件的另一种方法(viewWithTag)

在nib文件的属性设置中有一个地可以直接设置其tag值,如图:

Tag

这个值理论上来说在一个视图中应该唯一,也可以通过代码设置这个值:

1
[self.btn setTag: 1000];

设置了这个值之后,便可以通过以下方法,取得nib中的控件:

1
UIButton *button = (UIButton *)[self.view viewWithTag:100];

至此,基本可以自己动手开发一个属于你自己的iOS应用程序了。这里是一个根据本文内容编写的一个小的例子,功能很简单:点击第一个按钮,改变第二个按钮的名称。有兴趣的朋友可以下载去玩玩。