再下面,找到这两行代码:
58
59
60
|
- (IBAction)openWebsite:(id)sender { } |
觉得眼熟?之前在ContactViewController.h当中,系统确实自动生成了类似的代码,不过在.h文件中的代码只是一种“声明”,真正编写方法函数还是要在.m文件中进行。具体来说,我们需要将按钮的反映行为编写到这里。
你还可以在.m文件中找到类似下面这样的代码:
53
54
55
56
|
- ( void ) dealloc { [websiteButton release]; [super dealloc]; } |
这段代码与内存管理有关。内存管理对于移动应用编程来说是非常重要的,因为移动设备在内存方面的资源确实很有限。当websiteButton属性被定义时,通过“retain”参数,系统会将一部分内存分配给这个属性。“retain”的具体作用是告诉系统分配出一定的内存,并且在我们进一步下达命令之前不要将这部分内存收回。
而“dealloc”方法只会在当前View的实例被销毁时执行,所以在这个方法中添加“websiteButton release”就相当于告诉系统:“你可以在这里收回这部分内存资源了,我们不再需要它了”。如果没有这行代码,那么即使界面已经切换、websiteButton不再存在,这部分内存依然在被占用;这种情况就叫做“内存泄漏(memory leak)”。如果在开发过程中不做相关处理,那么这种情况就会逐渐累加起来,导致程序运行效率低下甚至崩溃,或是造成系统电量损耗等其他不良后果。
幸运的是,对应着iOS 5以上版本的SDK当中增加了ARC机制(Automatic Reference Counting),它可以帮助我们进行自动化的内存管理。在创建新项目的时候,你可以选择是否启用ARC。在当前案例中,我们并没有用到它,因为我们要在这里对相关知识进行简要的介绍。
代码绑定
之前使用辅助编辑器为按钮自动创建属性和方法的时候,系统不仅帮我们生成了相关的代码,而且还对按钮控件与相关代码进行了绑定。
选择ContactViewController.xib,展开文档结构列表,在“Placeholders”下,选择“File\’s Owner”,它所代表的就是整个ContactViewController类。现在到Xcode右侧,打开连接检查器(Connections inspector),看上去应该是这样的:
在“Outlets”当中,我们可以看到,websiteButton属性已经被关联到了.xib文件的按钮控件上。
而在“Received Actions”里,openWebsite方法也已经与该按钮的“Touch Up Inside”事件建立了关联。这个事件所代表的就是用户在界面中轻触按钮并抬起手指的整个动作,它是按钮控件的默认事件。
手动编写Objective-C代码
接下来我们要告诉按钮在被点击之后应该做些什么。
在ContactViewController.m中,将定义openWebsite方法的代码更新为:
58
59
60
61
|
- (IBAction)openWebsite:(id)sender { NSURL *webAddress = [NSURL URLWithString:@ "http:www.apple.com" ]; [[UIApplication sharedApplication] openURL:webAddress]; } |
在这段代码中,我们做了两件事。
首先,我们在第59行的代码中创建了一个临时变量“webAddress”,用来存储一段包含特定URL(http:\’\’www.apple.com”)的字符串。这里的写法是一种比较快捷的方式,系统可以自动为NSURL实例分配内存,也会在需要的时候自动释放。
而后面的代码则告诉系统可以使用相关的应用(例如Safari)来打开这个链接。
对于Contact界面中的其他按钮,我们也可以通过类似的步骤来设定响应规则。将上面代码中的“openURL:”替换为“mailto:”,可以使应用触发默认邮件客户端执行相关的邮件工作,而“tel:”则可调出系统的拨号键盘界面,直接拨打预设好的电话号码。
使界面以模态的方式呈现
当前的Portfolio界面中有一些作品的缩略图,我们希望用户在点击它们的时候,对应的大图可以弹出。
要实现这一点,我们可以创造模态视图,使新界面以动画过渡的方式呈现出来,并覆盖在其他界面之上。
创建模态视图
要创建模态视图并不难。首先,我们要创建一个新的类,名字叫做BigImageViewController,具体方式与我们之前创建3个自定义类是相同的。
然后打开BigImageViewController.xib文件,向界面中添加一个Image View作为图片容器,并将它的“Image”设置为portfolio-modal-bg.png图片文件。接下来,在左上角添加一个类型为“Custom”的圆角按钮控件,使用button-close.png作为其背景,并将字色设置为白色,文案为“Close”。
然后在现有界面基础上再添加一个Image View,大致尺寸和位置如下图所示:
切换至辅助编辑器模式,在新添加的空白Image View上执行Control+拖拽,并指向BigImageViewController.h代码当中@interface与@end之间的部分,以此方法分别建立名为“imageFrame”的Outlet,以及名为“closeView”的Action。系统将在.h文件中自动添加如下代码:
13
14
|
@property (retain, nonatomic) IBOutlet UIImageView *imageFrame; - (IBAction)closeView:(id)sender; |
而具体的closeView代码还需要我们手动添加到.m文件当中:
57
58
59
|
- (IBAction)closeView:(id)sender { [self dismissModalViewControllerAnimated:YES]; } |
这段代码的作用是关闭当前已经激活的模态视图界面。
加载模态界面的代码
回到标准编辑器模式,打开PortfolioViewController.h文件,将代码手动更新为:
9
10
11
12
13
14
15
|
#import <UIKit/UIKit.h> #import "BigImageViewController.h" @interface PortfolioViewController : UIViewController @property (nonatomic, retain) UIImage *bigImage; - (IBAction) selectImage1; - ( void ) openBigImageView; @end |
我们新写了一行#import代码,用来将之前新建的BigImageViewController类引入到PortfolioViewController当中,这样我们就可以在Portfolio界面中与之通讯,在需要的时候告诉BigImageViewController为自己创建一个实例。
我们还为PortfolioViewController创建了一个属性和两个方法,其中第二个方法openBigImage并不需要与.xib文件中的任何控件建立关联,所以它的返回类型是“void”,而非“IBAction”。
你也许会觉得奇怪,为什么在这里创建属性和方法的时候,我们没有使用副主编辑模式,通过拖拽方法来实现。其实结果是相同的,只是我们在这里刻意使用手动编码的方式来练习一下。所以接下来,我们还要到.m文件中手动输入那些与“属性合成”以及内存释放相关的代码:
11
12
13
14
15
16
|
@implementation PortfolioViewController @synthesize bigImage; - ( void ) dealloc { [bigImage release]; [super dealloc]; } |
在dealloc函数的后面,我们要为两个新建的方法编写具体的代码:
20
21
22
23
24
25
26
27
28
29
|
- (IBAction) selectImage1 { self.bigImage = [UIImage imageNamed: @ "image1-big.png" ]; [self openBigImageView]; } - ( void ) openBigImageView { BigImageViewController *bigImageView = [[[BigImageViewController alloc] initWithNibName:@ "BigImageViewController" bundle:nil] autorelease]; bigImageView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:bigImageView animated:YES]; [bigImageView.imageFrame setImage:bigImage]; } |
这次还真是输入了不少东西,我们来看看这些代码的作用是什么。
selectImage1方法为bigImage属性指定了具体的图片,即image1-big.png文件。同时该方法还调用执行了openBigImageView方法。
在openBigImageView中,我们首先创建了一个BigImageViewController类的实例,并将其命名为“bigImageView”。这个实例自身就是一个模态界面,它会以“翻转(flip)”的动画效果出现,并将bigImage作为具体的图片放到其imageFrame容器当中。
因为我们通过代码手动为BigImageViewController的实例分配了内存,所以我们还要在适当的时候将这部分内存释放。问题在于,我们并不知道这些资源会被使用多久,因为大图模态界面会打开多长时间是取决于用户的。要解决这个问题,我们需要使用autorelease命令,它会告诉iOS系统一直保持内存资源的分配状况,直到确认“安全”的时候再进行释放。
模态视图的代码绑定
现在我们需要将代码绑定到XIB当中的控件上。选择PortfolioViewController.xib文件,点击文档结构列表当中的“File\’s Owner”,然后打开右侧的连接检查器(Connections inspector)。
在“Received Action”中,我们可以看到之前编写的selectImage1方法,它的右侧是一个圆环。点击这个圆环并进行拖拽,一直拖到界面当中的第一个缩略图上面释放,如下图所示:
在弹出的列表当中选择“Touch Up Inside”事件。
试着运行一下我们的应用叭,如果之前的工作没有出现问题的话,现在我们应该可以在Portfolio界面中点击第一个缩略图并查看相应的大图了。
接下来,你可以自己试着对另外三个缩略图进行处理了。你需要创建selectImage2,selectImage3,selectImage4这三个新的方法,不过对于openBigImage方法来说就不需要重复创建了,它是可以被共用的。另外你也可以尝试为模态界面使用不同的动画过渡效果,包括
- UIModalTransitionStyleCoverVertical
- UIModalTransitionStyleCrossDissolve
- UIModalTransitionStyleFlipHorizontal
- UIModalTransitionStylePartialCurl
如果你在这个过程中遇到麻烦,也可以打开模板包,在End Result路径中找到最终完成版的文件进行参考。
总结
本文确实涵盖了不少方面的内容,从Xcode的界面介绍、基本操作,到在Interface Builder中创建界面,以及实际代码的编写。我们通过一个简单而具有代表性的案例了解了iOS应用开发当中的一些关键概念,包括类、属性、方法、内存管理等。
本文只是引领你入门的一个小小的起点。在此基础上,你可以通过更多的资源进一步深入学习iOS开发的相关知识与技能了。好运叭!
本文链接:http://www.mobileui.cn/ios-application-development-basic-knowledge.html本文标签: IOS, iOS应用, iOS开发, Web应用, 前端, 应用, 移动应用, 设计