iPhone如何本地化NIBvs 如何添加资源文件件

iphone3开发基础教程 - 全本 - 免费下载 - 计算机书籍控
Iphone3开发基础教程
作者: 马克(Dave Mark)
《iphone3开发基础教程》是Amazon计算机榜首图书,创造销售奇迹的经典著作,针对iPhoe SDK 3新特性全面改版,从这里,拥抱软件开发的未来。Apple公司的iPflone开创了移动平台新纪元!而最新版iPhone 3做了不少改进,如强化应用程序对GPS的支持,还增加了众多新功能,如全系统搜索、支持复制和粘贴、收发多媒体信息等。iPhone 3与App Store的绝配为全世界的程序员提供了一个施展才华的全新大舞台。只要有新奇的创意,你完全有可能像开发iStloot游戏的Ethan Nicliolas(日收入2万多美元)和开发Trism游戏的Steve Demmeter(月收入超过10万美元)那样,单枪匹马即可赢得全球市场,成功创业,改变自己的人生。上一版英文原版问世以来在Anlazor、计算机图书排行榜持续雄踞榜首,总排名一度在20名左右,被奉为经典。而中文版出版后也迅速荣登各大网店排行榜榜首,并创造了半年内印刷四次的销售奇迹。书中从到Apple网站注册账号,下载和安装免费iPhone SDK开始,清晰透彻地讲述了创建iPhone应用程序的全过程。作者在探讨基本概念和各个关键特性(iPhone界面元素、数据保存、SQLite3、Quarrtz和OpenGL ES、手势支持、本地化、Core Location等)时,提供了丰富的实例。更难得的是,《iphone3开发基础教程》始终强调iPhone开发中的各种最佳实践,即使是有经验的开发人员,也会因此受益匪浅。《iphone3开发基础教程》新版针对iPhone SDK 3做了大幅修订,力求使新老读者都能觉得物有所值。作者在纠正上一版错误的基础上,不仅更新了所有项目代码,使之兼容新旧SDK,还新增了不少内容,进一步阐明一些读者反馈的比较难懂的主题。此外,书中还为Core Data增加了一个新项目。立即展卷阅读,开始神奇的iPhone开发之旅吧。
第1章 欢迎来到iPhone的世界 1
1.1 关于本书 1
1.2 必要条件 1
1.3 必备知识 3
1.4 编写iPhone应用程序有何不同 4
1.4.1 只有一个正在运行的应用程序 4
1.4.2 只有一个窗口 4
1.4.3 受限访问 5
1.4.4 有限的响应时间 5
1.4.5 有限的屏幕大小 5
1.4.6 有限的系统资源 5
1.4.7 不支持垃圾收集 6
1.4.8 新功能 6
1.4.9 与众不同的方法 6
1.5 本书内容 6
1.6 本次更新的内容 7
1.7 准备开始吧 7
第2章 创建基本项目 8
2.1 在Xcode中设置项目 8
2.2 Interface Builder简介 13
2.2.1 nib文件的构成 14
2.2.2 在视图中添加标签 15
2.3 美化iPhone应用程序 17
2.4 小结 20
第3章 处理基本交互 21
3.1 MVC范型 21
3.2 创建项目 22
3.3 创建视图控制器 22
3.3.1 输出口 23
3.3.2 操作 24
3.3.3 将操作和输出口添加到视图控制器 24
3.3.4 将操作和输出口添加到实现文件 26
3.4 使用应用程序委托 30
3.5 编辑MainWindow.xib 33
3.6 编辑Button_FunViewController.xib 34
3.6.1 在Interface Builder中创建视图 34
3.6.2 连接所有元素 36
3.6.3 测试 39
3.7 小结 39
第4章 更丰富的用户界面 40
4.1 满是控件的屏幕 40
4.2 活动、静态和被动控件 42
4.3 创建应用程序 42
4.3.1 导入图像 42
4.3.2 实现图像视图和文本字段 43
4.3.3 添加图像视图 44
4.3.4 添加文本字段 47
4.3.5 设置第二个文本字段的属性 50
4.3.6 连接输出口 50
4.4 构建和运行 51
4.4.1 完成输入后关闭键盘 51
4.4.2 通过触摸背景关闭键盘 52
4.5 实现滑块和标签 54
4.5.1 确定输出口 54
4.5.2 确定操作 54
4.5.3 添加输出口和操作 54
4.5.4 添加滑块和标签 55
4.5.5 连接操作和输出口 56
4.6 实现开关、按钮和分段控件 57
4.6.1 确定输出口 57
4.6.2 确定操作 57
4.6.3 添加开关、按钮和分段控件 59
4.6.4 连接开关输出口和操作 60
4.6.5 添加按钮 61
4.7 实现操作表和警报 62
4.7.1 遵从操作表委托方法 62
4.7.2 显示操作表 62
4.7.3 操作表委托和创建警报 64
4.8 美化按钮 66
4.8.1 viewDidLoad方法 66
4.8.2 控件状态 67
4.8.3 可拉伸图像 67
4.9 成为出色的内存使用者 67
4.10 小结 68
第5章 自动旋转和自动调整大小 70
5.1 使用自动调整属性处理旋转 71
5.1.1 指定旋转支持 71
5.1.2 使用自动调整属性设计界面 73
5.1.3 自动调整属性 74
5.1.4 设置按钮的自动调整属性 75
5.2 在旋转时重构视图 76
5.2.1 声明和连接输出口 77
5.2.2 在旋转时移动按钮 77
5.3 切换视图 79
5.3.1 确定输出口 80
5.3.2 确定动作 80
5.3.3 声明动作和输出口 80
5.3.4 设计两个视图 81
5.3.5 实现交换和动作 82
5.4 小结 84
第6章 多视图应用程序 85
6.1 View Switcher应用程序 87
6.2 多视图应用程序的体系结构 88
6.3 构建View Switcher 88
6.3.1 创建视图控制器和nib文件 89
6.3.2 修改应用程序委托 91
6.3.3 SwitchViewController.h 92
6.3.4 修改MainWindow.xib 92
6.3.5 编写SwitchViewController.m 95
6.3.6 实现内容视图 98
6.4 制作转换动画 101
6.5 小结 103
第7章 标签栏与选取器 104
7.1 Pickers应用程序 104
7.2 委托和数据源 106
7.3 建立工具栏框架 106
7.3.1 创建文件 107
7.3.2 添加根视图控制器 108
7.4 实现日期选取器 112
7.5 实现单个组件选取器 114
7.5.1 声明输出口和操作 114
7.5.2 构建视图 115
7.5.3 将控制器实现为数据源和委托 115
7.6 实现多组件选取器 120
7.6.1 声明输出口和操作 120
7.6.2 构建视图 120
7.6.3 实现控制器 121
7.7 实现独立组件 123
7.8 使用自定义选取器创建简单游戏 130
7.8.1 编写控制器头文件 130
7.8.2 构建视图 130
7.8.3 添加图像资源 131
7.8.4 实现控制器 131
7.8.5 spin方法 134
7.8.6 viewDidLoad方法 135
7.8.7 最后的细节 137
7.8.8 链接Audio Toolbox框架 140
7.9 小结 141
第8章 表视图简介 142
8.1 表视图基础 142
8.2 实现一个简单的表 145
8.2.1 设计视图 145
8.2.2 编写控制器 146
8.3 添加一个图像 149
8.4 附加配置 151
8.4.1 设置缩进级别 152
8.4.2 处理行的选择 152
8.4.3 更改字体大小和行高 154
8.4.4 委托还能做什么 155
8.5 定制表视图单元 155
8.5.1 单元应用程序 155
8.5.2 向表视图单元添加子视图 156
8.5.3 使用UITableViewCell的自定义子类 159
8.6 分组分区和索引分区 163
8.6.1 构建视图 163
8.6.2 导入数据 164
8.6.3 实现控制器 164
8.6.4 添加索引 168
8.7 实现搜索栏 168
8.7.1 重新考虑设计 168
8.7.2 深层可变副本 169
8.7.3 更新控制器头文件 170
8.7.4 修改视图 171
8.7.5 修改控制器实现 173
8.8 小结 183
第9章 导航控制器和表视图 184
9.1 导航控制器 184
9.1.1 栈的性质 184
9.1.2 控制器栈 185
9.2 由6个部分组成的分层应用程序:Nav 185
9.3 构建Nav应用程序的骨架 188
9.3.1 创建第一级视图控制器 188
9.3.2 设置导航控制器 189
9.4 第一个子控制器:展示按钮视图 194
9.5 第二个子控制器:校验表 201
9.6 第三个子控制器:表行上的控件 205
9.7 第四个子控制器:可移动的行 211
9.7.1 编辑模式 211
9.7.2 创建一个新的二级控制器 212
9.8 第五个子控制器:可删除的行 217
9.9 第六个子控制器:可编辑的详细窗格 222
9.9.1 创建数据模型对象 222
9.9.2 创建控制器 224
9.9.3 创建详细视图控制器 227
9.10 其他内容 240
9.11 小结 243
第10章 应用程序设置和用户默认设置 244
10.1 设置束 244
10.2 AppSettings应用程序 245
10.3 创建项目 247
10.4 使用设置束 248
10.4.1 在项目中添加设置束 248
10.4.2 设置属性列表 249
10.4.3 添加文本字段设置 250
10.4.4 添加安全文本字段设置 252
10.4.5 添加多值字段 252
10.4.6 添加拨动开关设置 253
10.4.7 添加滑块设置 254
10.4.8 添加子设置视图 255
10.5 读取应用程序中的设置 256
10.6 更改应用程序中的默认设置 260
10.7 小结 263
第11章 基本数据持久性 264
11.1 应用程序的沙盒 264
11.1.1 获取Documents目录 265
11.1.2 获取tmp目录 266
11.2 文件保存策略 266
11.2.1 单个文件持久性 266
11.2.2 多个文件持久性 267
11.3 持久保存应用程序数据 267
11.4 持久性应用程序 268
11.4.1 创建持久性项目 269
11.4.2 设计持久性应用程序视图 269
11.4.3 编辑持久性类 270
11.4.4 对模型对象进行归档 273
11.4.5 实现NSCopying 275
11.5 归档应用程序 276
11.5.1 实现FourLines类 277
11.5.2 实现PersistenceView-Controller类 278
11.6 使用iPhone的嵌入式SQLite3 280
11.7 使用Core Data 289
11.7.1 实体和托管对象 291
11.7.2 键/值编码 292
11.7.3 在上下文中结合它们 292
11.7.4 创建新托管对象 293
11.7.5 检索托管对象 293
11.7.6 设计数据模型 294
11.7.7 创建持久视图和控制器 297
11.7.8 将持久视图控制器设置为应用程序的根控制器 302
11.8 小结 303
第12章 使用Quartz和OpenGL绘图 304
12.1 图形世界的两个视图 304
12.2 本章的绘图应用程序 305
12.3 Quart绘图方法 305
12.3.1 Quartz 2D的图形上下文 305
12.3.2 坐标系 306
12.3.3 指定颜色 307
12.3.4 在上下文中绘制图像 308
12.3.5 绘制形状:多边形、直线和曲线 309
12.3.6 Quartz 2D工具示例:模式、梯度、虚线模式 309
12.4 构建QuartzFun应用程序 309
12.4.1 创建随机颜色 310
12.4.2 定义应用程序常量 311
12.4.3 实现QuartzFunView框架 312
12.4.4 向视图控制器中添加输出口和操作 314
12.4.5 更新QuartzFunViewContro-ller.xib 316
12.4.6 绘制直线 317
12.4.7 绘制矩形和椭圆形 319
12.4.8 绘制图像 320
12.4.9 优化QuartzFun应用程序 322
12.5 一些OpenGL ES基础知识 325
12.5.1 构建GLFun应用程序 326
12.5.2 设计Nib、添加框架、运行应用程序 335
12.6 小结 335
第13章 轻击、触摸和手势 336
13.1 多触摸术语 336
13.2 响应者链 337
13.3 多触摸体系结构 338
13.4 触摸浏览器应用程序 339
13.5 Swipes应用程序 342
13.6 实现多个轻扫动作 345
13.7 检测多次轻击 347
13.8 检测捏合操作 351
13.9 自己定义手势 354
13.10 小结 358
第14章 使用Core Location定位功能 359
14.1 位置管理器 359
14.1.1 设置所需的精度 360
14.1.2 设置距离筛选器 360
14.1.3 启动位置管理器 360
14.1.4 更明智地使用位置管理器 360
14.2 位置管理器委托 361
14.2.1 获取位置更新 361
14.2.2 使用CLLocation获取纬度和经度 361
14.2.3 错误通知 362
14.3 尝试使用Core Location 363
14.3.1 更新位置管理器 367
14.3.2 确定移动距离 367
14.4 小结 368
第15章 加速计 369
15.1 加速计物理学 369
15.2 访问加速计 370
15.2.1 UIAcceleration 370
15.2.2 实现accelerometer: didAccelerate:方法 371
15.3 摇动与击碎 373
15.3.1 用于击碎的代码 373
15.3.2 加载模拟文件 376
15.3.3 完好如初——复原触摸 377
15.4 滚弹珠程序 377
15.4.1 实现Ball View控制器 378
15.4.2 编写Ball View 379
15.4.3 计算小球运动 382
15.5 小结 385
第16章 iPhone照相机和照片库 386
16.1 使用图像选取器和UIImagePicker-Controller 386
16.2 实现图像选取器控制器委托 387
16.3 实际测试照相机和库 389
16.3.1 设计界面 390
16.3.2 实现照相机视图控制器 390
16.4 小结 394
第17章 应用程序本地化 395
17.1 本地化体系结构 395
17.2 使用字符串文件 396
17.3 现实中的iPhone:本地化应用程序 398
17.3.1 查看当前区域设置 401
17.3.2 测试LocalizeMe 401
17.3.3 本地化nib文件 402
17.3.4 查看本地化的项目结构 403
17.3.5 本地化图像 405
17.3.6 本地化应用程序图标 406
17.3.7 生成和本地化字符串文件 406
17.4 小结 409
第18章 未来之路 410
18.1 别陷进单一的思路里 410
18.1.1 苹果公司的文档 410
18.1.2 邮件列表 411
18.1.3 论坛 411
18.1.4 网站 411
18.1.5 博客 412
18.1.6 Dave和Jeff的博客及Twitter 412
18.1.7 参考图书 412
18.1.8 如果仍未解决问题 412
18.2 再会 412
密码:wrff什么是Nib文件?(Nib文件是一种特殊类型的资源文件,它用于保存iPhone OS或Mac OS X应用程序的用户接口)
时间: 16:43:31
&&&& 阅读:175
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&Nib文件是一种特殊类型的资源文件,它用于保存iPhone OS或Mac OS X应用程序的用户接口。Nib文件是Interface Builder文档。通常您会使用Interface Builder设计应用程序的可视部分-例如窗口或视图。有些时候,您可能也用它来配置一些不可视的对象,例如控制器对象(用于管理窗口和视图)。实际上,所有这些操作都是在编辑一份Interface Builder文档,即在创建一份对象图。保存文件的时候,就是将该对象图进行归档,加载文件的时候,就是将对象图进行解档。
Nib文件&也就是对象图-可以包含占位对象,这种对象用于指涉存在于文档之外的对象。这些对象虽然不在文档中,但却可能含有文档内对象的引用,或者被文档内的对象引用。文件拥有者就是一种特殊的占位对象。
在程序运行的时候,您可以使用&loadNibNamed:owner:(或者此方法变种)加载Nib文件。在Nib文件中,文件拥有者是个占位对象,它表示您通过owner参数传给此方法的对象。加载Nib文件的时候,所有在Interface Builder中建立的关联(文件拥有者和其他对象之间的关联)都能够在运行时重新建立起来。
nib文件是一种数据文件,用于存储可在应用程序需要时使用的一些&冻结&的对象。大多数情况下,应用程序使用nib文件来存储构成用户界面的窗口和视图。当您将nib文件载入应用程序时,nib装载代码会将文件中的内容转化为应用程序可以操作的真正对象。通过这个机制,nib文件省去了用代码创建那些对象的工作。
Interface Builder是一个可视化的设计环境,您可以用它来创建nib文件。您可以将标准对象(比如UIKit框架中提供的窗口和视图)和Xcode工程中的定制对象放到nib文件中。在Interface Builder中创建视图层次相当简单,只需要对视图对象进行简单拖拽就可以了。您也可以通过查看器窗口来配置每个对象的属性,以及通过创建对象间的连接来定义它们在运行时的关系。您所做的改变最终都会作为nib文件的一部分存储到磁盘上。
在运行时,当您需要nib文件中包含的对象时,就将nib文件装载到程序中。典型情况下,装载nib文件的时机是当用户界面发生变化和需要在屏幕上显示某些新视图的时候。如果您的应用程序使用视图控制器,则视图控制器会自动处理nib文件的装载过程,当然,您也可以通过类的方法自行装载。
初始化的另一个任务是装载应用程序的主nib文件。如果应用程序的信息属性列表(Info.plist)文件中含有NSMainNibFile键,则作为初始化过程的一个部分,UIApplication对象会装载该键指定的nib文件。主nib文件是唯一一个自动装载的nib文件,其它的nib文件可以在稍后根据需要进行装载。
Nib文件是基于磁盘的资源文件,用于存储一或多个对象的快照。iPhone应用程序的主nib文件通常包含一个窗口对象和一个应用程序委托对象,还可能包含一个或多个管理窗口的其它重要对象。装载一个nib文件会使该文件中的对象被重新构造,从而将每个对象的磁盘表示转化为应用程序可以操作的内存对象。从nib文件中装载的对象和通过编程方式创建的对象之间没有区别。然而,对于用户界面而言,以图形的方式(使用Interface Builder程序)创建与用户界面相关联的对象并将它们存储在nib文件中通常比以编程的方式进行创建更加方便。标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://www.cnblogs.com/kenshinobiy/p/4864373.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!《iPhone开发基础教程》[90页]
推荐理由:
免积分绿色下载通道:不用登录、不要积分,您需要做的仅仅是填写一个正确的邮箱,点击发送后即可收到包含下载地址的邮件。
邮箱地址:
&&验证码:
是否接受文库或文档上传者,为您提供更多信&&&息服务。
您将会在3分钟内,收到一封包含下载地址的邮件。
温馨小提示:如果在收件箱里没有找到,也许它就藏在垃圾箱哦!
每个邮箱只能免费下载10篇文档,所以请您账号后再进行下载。
To view this page ensure that Adobe Flash Player version
9.0.124 or greater is installed.
广告剩余:秒
大小: 19.48 MB
所需金币:0
Amazon 计算机榜首图书
创造销售奇迹的最新经典著作
全面深入探索 iPhone 开发的无限可能
从这里,抢先拥抱软件开发的未来
国内最大、最专业iPhone开发社区CocoaChina强烈推荐
“Dave Mark一直是Mac编程图书作者中的佼佼者,而他现在又无可争议地成为了iPhone
开发图书的王牌作者!本书是iPhone开发的权威指南,任何有意开始iPhone开发的人都应该阅读这
本宝贵的参考指南。”
——Brian Greenstone(Pangea软件公司的总裁兼CEO)
“Trism游戏让我在2个月内收入25万美元,然后有无数人问我怎么开发iPhone应用,现在
答案出现了!Dave和Jeff的书深入浅出、循序渐进而且示例丰富,堪称完美。它已经成了我
的必备参考书,需要不时查阅。强烈推荐!”
——Steve Demeter(《连线》杂志“2008最佳iPhone应用”Trism游戏开发者)
Apple公司的iPhone已经开创了移动平台新纪元!它与App Store的绝配也为全世界的程
序员提供了一个施展才华的全新大舞台。只要有新奇的创意,你完全有可能像开发iShoot游
戏的Ethan Nicholas(日收入2万多美元)和开发Trism游戏的Steve Demeter(月收入超过10万
美元)那样,仅凭单枪匹马就赢得全球市场,成功创业,改变自己的人生。
本书由业界名家撰写,英文原版问世以后迅速登上Amazon计算机图书排行榜榜首并持
续至今,总排名一度达到20名左右,创造了销售奇迹。而且,本书获得了读者的一致好评,
已经被奉为经典。书中从到Apple网站注册账号,下载和安装免费iPhone SDK开始,清晰透
彻地讲述了创建iPhone应用程序的全过程。在探讨基本概念和各个关键特性(iPhone界面元
素、数据保存、SQLite、Quartz和OpenGL ES、手势支持、本地化、Core Location等)时,
提供了丰富的实例。更难得的是,本书始终强调iPhone开发中的各种最佳实践,即使是有经
验的开发人员,也会因此受益匪浅。
开卷阅读本书,进入iPhone开发的神奇世界吧,它将让你热血沸腾!
Dave Mark 深受爱戴的Apple技术开发专家,具有多年开发经验。他是许多Mac平台畅销书
的作者,包括Learn C on the Mac、Macintosh Programming Primer系列以及Ultimate Mac
Programming。可以通过www.davemark.com与他联系。
Jeff LaMarche 资深Apple平台专家,拥有多年企业级开发经验。他是MacTech Magazine和
Apple公司开发人员网的专栏作家。
iPhone自从发布的那一天起就成为科技界的焦点。但一直为人诟病的是,其本身并不支持开
源软件开发,也一直没有推出相应的第三方开发工具。而iPhone SDK的发布无疑解决了这一难题。
开发人员可以使用iPhone SDK轻易地为iPhone和iPod Touch创建应用程序。其简单易学的操作方
式和强大的功能为开发人员带来了超强的能力。
本书提供了关于iPhone SDK和iPhone开发的全面信息,对Objective-C编程语言、Xcode和
Interface Builder开发工具进行了深入浅出的介绍,同时对iPhone开发的基本流程、原理和原则进
行了详细和通俗的讲解。本书采用理论与实践相结合的方式,指导读者创建一系列应用程序,让
读者能在实践中理解iPhone应用程序的运行方式和构建方式,掌握具体的iPhone特性,学会如何
控制这些特性或与之交互。
全书共18章,分为3个部分。前4章介绍iPhone开发中的相关基本概念和开发人员所需的必备
知识,并通过示例演示了一些标准的iPhone用户界面控件。第5章至第16章深入介绍如何开发各
种高级iPhone特性,其中包括自动旋转、工具栏控制器、表视图、分层列表、应用程序设置、数
据管理、绘图、手势输入、Core Location、加速计以及照相机和相片库。最后两章介绍如何将iPhone
应用程序翻译为其他语言,从而让更多的用户接受并使用它,以及看完本书之后应该努力的方向。
本书覆盖面广、结构清晰,是一本有关iPhone开发的全新入门指南。它面向具备基本
Objective-C知识的iPhone初、高级开发用户,不论你是经验丰富的开发人员,还是初涉编程领域
的新手,都可以从本书中得到有用的信息。书中的示例通用性高,特别适合读者参考使用,这使
本书成为广大读者的首选。
iPhone SDK是一个新兴的软件开发平台,但目前国内关于iPhone开发的资料非常有限。相信
本书的出版可以为iPhone开发的发展起到推波助澜的作用。
本书由漆振、谢巧云、孙文磊等翻译,在翻译过程中得到了欧阳宇、盛海艳、杨越和张波的
帮助,在此一并致谢。由于译者的知识水平有限,加之时间也比较仓促,文中难免会出现一些疏
漏,恳请广大读者给予批评指正。
“从我开始使用Mac以来,我还没有看到过让我如此激动的编程平台。”最近我们经常听到这
样的感言,坦白地说,我也有同感。iPhone是一种让人激动不已的出色技术,它将功能和乐趣完
美地融合在一起。而程序员使用这种技术可以完成的工作也让人很激动!
这个世界的大门刚刚打开。花些时间浏览App Store,你会情不自禁地感动振奋。如果你并不
负责设计自己的iPhone应用程序,那么为iPhone开发提供咨询也具有无限的商机。每个人好像都
想把他们的产品导入该平台。我们的电话已经响个不停了。
如果你已经研究了几个月,偶尔访问一下我们的网站(http://iphonedevbook.com),并和我们
打个招呼吧。请告诉我们有关你的项目的信息,我们很乐意倾听你的诉说。
Dave和Jeff
第 1 章 欢迎来到 iPhone 的世界 1
1.1 关于本书 1
1.2 必要条件 1
1.3 必备知识 3
1.4 编写 iPhone 应用程序有何不同 4
1.4.1 只有一个正在运行的应用程序 4
1.4.2 只有一个窗口 4
1.4.3 受限访问 4
1.4.4 有限的响应时间 4
1.4.5 有限的屏幕大小 5
1.4.6 有限的系统资源 5
1.4.7 缺少 Cocoa 工具 5
1.4.8 新属性 5
1.4.9 与众不同的方法 6
1.5 本书内容 6
1.6 准备开始吧 7
第 2 章 创建基本项目 8
2.1 在 Xcode 中设置项目 8
2.2 Interface Builder 简介 12
2.2.1 nib 文件的构成 14
2.2.2 在视图中添加标签 15
2.3 iPhone 美化 17
2.4 小结 20
第 3 章 处理基本交互 21
3.1 模型—视图—控制器范型 21
3.2 创建项目 22
3.3 创建视图控制器 22
3.3.1 输出口 23
3.3.2 操作 23
3.3.3 将操作和输出口添加到视图控制器 24
3.3.4 将操作和输出口添加到实现文件 26
3.4 使用应用程序委托 30
3.5 编辑 MainWindow.xib 32
3.6 编辑 Button_FunViewController.xib 33
3.6.1 在 Interface Builder 中创建视图 33
3.6.2 连接所有元素 35
3.6.3 测试 37
3.7 小结 38
第 4 章 更丰富的用户界面 39
4.1 满是控件的屏幕 39
4.2 活动、静态和被动控件 41
4.3 创建应用程序 41
4.3.1 导入图像 41
4.3.2 实现图像视图和文本字段 42
4.3.3 添加图像视图 43
4.3.4 添加文本字段 46
4.3.5 设置第二个文本字段的属性 49
4.3.6 连接输出口 49
4.4 构建和运行 49
4.4.1 完成输入后关闭键盘 50
4.4.2 通过触摸背景关闭键盘 51
4.5 实现滑块和标签 52
4.5.1 确定输出口 52
4.5.2 确定操作 52
4.5.3 添加输出口和操作 52
4.5.4 添加滑块和标签 53
4.5.5 连接操作和输出口 54
4.6 实现开关和分段控件 55
4.6.1 确定输出口 55
4.6.2 确定操作 55
4.6.3 添加开关和分段控件 57
4.6.4 连接输出口 58
4.7 实现按钮、操作表和警报 59
4.7.1 将输出口及操作添加到控制器头文件 59
4.7.2 在 Interface Builder 中添加按钮 60
4.7.3 实现按钮的操作方法 60
4.8 显示操作表 61
4.9 美化按钮 63
4.9.1 viewDidLoad 方法 64
4.9.2 控件状态 65
4.9.3 可拉伸图像 65
4.10 小结 65
第 5 章 自动旋转和自动调整大小 67
5.1 使用自动调整属性处理旋转 68
5.1.1 指定旋转支持 68
5.1.2 使用自动调整属性设计界面 70
5.1.3 自动调整属性 70
5.1.4 设置按钮的自动调整属性 72
5.2 在旋转时重构视图 73
5.2.1 声明和连接输出口 74
5.2.2 在旋转时移动按钮 74
5.3 切换视图 77
5.3.1 确定输出口 78
5.3.2 确定动作 78
5.3.3 声明动作和输出口 79
5.3.4 设计两个视图 79
5.3.5 实现交换和动作 80
5.3.6 链接 Core Graphics 框架 83
5.4 小结 85
第 6 章 多视图应用程序 86
6.1 View Switcher 应用程序 88
6.2 多视图应用程序的体系结构 88
6.2.1 多视图控制器也是视图控制器 89
6.2.2 内容视图剖析 89
6.3 构建 View Switcher 89
6.3.1 创建视图控制器和 nib 文件 90
6.3.2 修改应用程序委托 92
6.3.3 SwitchViewController.h 93
6.3.4 修改 MainWindow.xib 93
6.3.5 编写 SwitchViewController.m 96
6.3.6 实现内容视图 99
6.4 制作转换动画 101
6.5 重构 103
6.6 小结 105
第 7 章 标签栏与选取器 106
7.1 Pickers 应用程序 106
7.2 委托和数据源 108
7.3 建立工具栏框架 108
7.3.1 创建文件 108
7.3.2 设置内容视图 nib 109
7.3.3 添加根视图控制器 109
7.4 实现日期选取器 113
7.5 实现单个组件选取器 116
7.5.1 声明输出口和操作 116
7.5.2 构建视图 116
7.5.3 将控制器实现为数据源和委托 117
7.6 实现多组件选取器 121
7.6.1 声明输出口和操作 121
7.6.2 构建视图 122
7.6.3 实现控制器 122
7.7 实现独立组件 125
7.8 使用自定义选取器创建简单游戏 132
7.8.1 编写控制器头文件 132
7.8.2 构建视图 133
7.8.3 添加图像资源 133
7.8.4 实现控制器 133
7.8.5 spin 方法 136
7.8.6 viewDidLoad 方法 137
7.8.7 最后的细节 139
7.8.8 链接 Audio Toolbox 框架 142
7.9 小结 143
第 8 章 表视图简介 144
8.1 表视图基础 144
8.2 实现一个简单的表 147
8.2.1 设计视图 147
8.2.2 编写控制器 148
8.3 添加一个图像 151
8.4 附加配置 151
8.4.1 设置缩进级别 152
8.4.2 处理行的选择 152
8.4.3 更改字体大小和行高 153
8.4.4 委托还能做什么? 155
8.5 定制表视图单元 155
8.5.1 单元应用程序 155
8.5.2 向表视图单元添加子视图 155
8.5.3 使用 UITableViewCell 的自定义子类 159
8.6 分组分区和索引分区 163
8.6.1 构建视图 163
8.6.2 导入数据 163
8.6.3 实现控制器 164
8.6.4 添加索引 167
8.7 实现搜索栏 168
8.7.1 重新考虑设计 168
8.7.2 深层可变副本 168
8.7.3 更新控制器头文件 170
8.7.4 修改视图 171
8.7.5 修改控制器实现 172
8.8 小结 180
第 9 章 导航控制器和表视图 181
9.1 导航控制器 181
9.1.1 栈的性质 181
9.1.2 控制器栈 182
9.2 由 6 个部分组成的分层应用程序:Nav 182
9.3 构建 Nav 应用程序的骨架 184
9.3.1 创建根视图控制器 185
9.3.2 设置导航控制器 185
9.4 第 1 个子控制器:展示按钮视图 191
9.5 第 2 个子控制器:校验表 198
9.6 第 3 个子控制器:表行上的控件 202
9.7 第 4 个子控制器:可移动的行 207
9.7.1 编辑模式 208
9.7.2 创建一个新的二级控制器 208
9.8 第 5 个子控制器:可删除的行 213
9.9 第 6 个子控制器:可编辑的详细窗格 218
9.9.1 创建数据模型对象 219
9.9.2 创建控制器 221
9.9.3 创建详细视图控制器 224
9.10 更多内容 238
9.11 小结 240
第 10 章 应用程序设置和用户默认设置 241
10.1 了解设置束 241
10.2 AppSettings 应用程序 242
10.3 创建项目 243
10.4 使用设置束 245
10.4.1 在项目中添加设置束 245
10.4.2 设置属性列表 246
10.4.3 添加文本字段设置 247
10.4.4 添加安全文本字段设置 249
10.4.5 添加多值字段 249
10.4.6 添加拨动开关设置 250
10.4.7 添加滑块设置 251
10.4.8 添加子设置视图 252
10.5 读取应用程序中的设置 253
10.6 更改应用程序中的默认设置 257
10.7 小结 259
第 11 章 基本数据持久性 260
11.1 应用程序的沙盒 260
11.1.1 获取 Documents 目录 261
11.1.2 获取 tmp 目录 262
11.2 文件保存策略 262
11.2.1 单个文件持久性 262
11.2.2 多个文件持久性 262
11.3 持久保存应用程序数据 263
11.4 持久性应用程序 264
11.4.1 创建持久性项目 264
11.4.2 设计持久性应用程序视图 265
11.4.3 编辑持久性类 265
11.4.4 对模型对象进行归档 269
11.4.5 实现 NSCopying 270
11.5 归档应用程序 272
11.5.1 实现 FourLines 类 272
11.5.2 实现 PersistenceViewController 类 273
11.6 使用 iPhone 的嵌入式 SQLite3 276
11.7 小结 284
第 12 章 使用 Quartz 和 OpenGL 绘图 285
12.1 图形世界的两个视图 285
12.2 本章的绘图应用程序 286
12.3 Quart 绘图方法 286
12.3.1 Quartz 2D 的图形上下文 286
12.3.2 坐标系 287
12.3.3 指定颜色 287
12.3.4 在上下文中绘制图像 289
12.3.5 绘制形状:多边形、直线和曲线 289
12.3.6 Quartz 2D 工具示例:模式、梯度、虚线模式 289
12.4 构建 QuartzFun 应用程序 290
12.4.1 创建随机颜色 291
12.4.2 定义应用程序常量 291
12.4.3 实现 QuartzFunView 框架 292
12.4.4 向视图控制器中添加输出口和操作 294
12.4.5 更新 QuartzFunViewController.xib 297
12.4.6 绘制直线 298
12.4.7 绘制矩形和椭圆形 299
12.4.8 绘制图像 301
12.5 一些 OpenGL ES 基础知识 306
12.6 小结 316
第 13 章 轻击、触摸和手势 317
13.1 多触摸术语 317
13.2 响应者链 318
13.3 多触摸体系结构 319
13.4 触摸浏览器应用程序 320
13.5 Swipe 应用程序 324
13.6 实现多个轻扫 327
13.7 检测多次轻击 329
13.8 检测捏合操作 333
13.9 自己定义手势 336
13.10 小结 339
第 14 章 我在哪里?使用 Core Location 定位功能 340
14.1 位置管理器 340
14.1.1 设置所需的精度 341
14.1.2 设置距离筛选器 341
14.1.3 启动位置管理器 341
14.1.4 更明智地使用位置管理器 341
14.2 位置管理器委托 342
14.2.1 获取位置更新 342
14.2.2 使用 CLLocation 获取纬度和经度 342
14.2.3 错误通知 343
14.3 尝试使用 Core Location 344
14.3.1 更新位置管理器 347
14.3.2 确定移动距离 348
14.4 小结 349
第 15 章 加速计 350
15.1 加速计物理学 350
15.2 访问加速计 351
15.2.1 UIAcceleration 351
15.2.2 实现 accelerometer:didAccelerate:方法 353
15.3 摇动与击碎 354
15.3.1 用于击碎的代码 355
15.3.2 加载模拟文件 358
15.3.3 完好如初——复原触摸 359
15.4 滚弹珠程序 359
15.4.1 实现 Ball View 控制器 360
15.4.2 编写 Ball View 361
15.4.3 计算小球运动 364
15.5 小结 366
第 16 章 iPhone 照相机和照片库 367
16.1 使用图像选取器和 UIImagePickerController 367
16.2 实现图像选取器控制器委托 368
16.3 实际测试照相机和库 370
16.3.1 设计界面 370
16.3.2 实现照相机视图控制器 371
16.4 小结 374
第 17 章 应用程序本地化 375
17.1 本地化体系结构 375
17.2 使用字符串文件 376
17.3 现实中的 iPhone:本地化应用程序 378
17.3.1 查看当前区域设置 381
17.3.2 测试 LocalizeMe 381
17.3.3 本地化 nib 文件 382
17.3.4 查看本地化的项目结构 383
17.3.5 本地化图像 385
17.3.6 本地化应用程序图标 386
17.3.7 生成和本地化字符串文件 386
17.4 小结 388
第 18 章 未来之路 390
18.1 答案揭晓 390
18.1.1 苹果公司的文档 390
18.1.2 邮件列表 391
18.1.3 论坛 391
18.1.4 网站 391
18.1.5 博客 391
18.1.6 如果仍未解决问题 392
18.2 再会 392
没有我们善良、能干又聪明的家人、朋友和同伴的支持,本书是不可能完成的。首先,感谢
Terry和Deneen对我们的宽容,他为我们专心写书提供了非常好的环境。这个项目耗费了相当长
的时间,但是你们从未抱怨过。我们很幸运!
本书的完成还要归功于Apress工作人员的合作。他们不仅是本书的出版者,还是我们不可多
得的朋友。Clay Andres策划了本书,并将我们带到了Apress。Dominic Shakeshaft始终带着微笑处
理我们的抱怨,并总能找到合适的解决方法,使本书完成得更好。Laura Esterman是一位亲切的
项目经理,她是我们实现每一个目标的动力。她让本书的编写能够有条不紊地进行,并为我们指
明了正确的方向。Heather Lang是个极为出色的文字编辑,很荣幸能和你一起工作,请下一次依
然做我们的文字编辑!Grace Wong和生产团队把零碎的稿件整合成书,Kari Brooks-Copony提供
了出色的版式设计。Kelly Winquist用我们的Word文档印刷出非常精美的页面。Pete Aylward征集
宣传素材,策划推出一系列营销活动。我们对Apress的所有工作人员表示由衷的感谢!
特别感谢我们优秀的技术审稿人Mark Dalrymple。除了提供具有独到见解的反馈之外,Mark
还测试了本书中的所有代码,帮助我们保证了本书的正确性。感谢您!
最后,感谢我们的孩子,他们在父亲努力工作时表现出非常好的耐心。本书是送给你们的:
Maddie、Gwynnie、Ian、Kai、Daniel、Kelley和Ryan。
1.2 必要条件 1
欢迎来到 iPhone 的世界
想编写iPhone应用程序?iPhone可能在今后很长一段时间内都是最有趣的新兴平台。毫
无疑问,它是迄今为止最新颖的移动平台,特别是现在,苹果公司还提供了一组精美
的、具有良好文档的工具来支持iPhone应用程序的开发。
1.1 关于本书
本书将带你走上创建iPhone应用程序的大道。我们的目标是让你通过初步学习,理解iPhone
应用程序的运行方式和构建方式。在阅读过程中,你将创建一系列小型应用程序,每个应用程序
都会突出特定的iPhone特性,展示如何控制这些特性或与其交互。如果将本书中的基本知识与你
自己的创造力相结合,同时借助苹果公司大量翔实的文档,你将具备创建专业级iPhone应用程序
所需的一切条件。
1.2 必要条件
在开始编写iPhone软件之前,需要做一些准备工作。对于初学者,需要一台运行Leopard(OS
X 10.5.3或更高版本)的基于Intel的Macintosh计算机。2006年之后上市的任何Macintosh计算机(不
管是笔记本还是台式机)应该都符合要求。
无需使用具备顶级配置的计算机,MacBook或Mac Mini就能够出色地完成任务。但是,对于
较早且运行速度较慢的计算机型号,进行RAM升级能够获得较大的性能提升。
你还需要注册成为iPhone开发人员。只有完成了这一步,苹果公司才允许下载iPhone SDK(软
件开发工具包)。
要进行注册,请访问http://developer.apple.com/iphone/(中文网站为http://www.apple.com.cn/
developer/iPhone/,如图1-1所示),该页面应该与图1-1中显示的页面类似。页面中提供了最新且
功能最强大的iPhone SDK的下载链接。单击该链接将进入包含3个选项的注册页面。
最简单(而且免费)的选项是单击Download the Free SDK按钮。页面将提示输入Apple ID。
使用你的Apple ID登录。如果还没有Apple ID,请单击Create Apple ID按钮,创建一个Apple ID,
然后再登录。登录之后,将进入iPhone开发主页面。其中不仅有SDK的下载链接,还提供了各类
文档、视频和示例代码等的链接,所有这些资源都能帮你进行iPhone应用程序开发。
2 第 1 章 欢迎来到 iPhone 的世界
图1-1 苹果公司的iPhone开发中心网站
iPhone SDK中包含的一个最重要的元素是Xcode,它是苹果公司的IDE(集成开发环境)。
Xcode提供了各种实用工具,用于创建和调试源代码,编译应用程序以及调优应用程序性能。学
习完本书,你将会迷恋上Xcode!
这个免费的SDK还包含一个仿真器,它支持在Mac上运行大多数iPhone程序。这对于学习如
何编写iPhone程序极其有用。但是,免费选项不支持将应用程序下载到实际的iPhone(或iPod
Touch)中。此外,它也不支持在苹果公司的iPhone App Store上分发应用程序。要实现这些功能,
需要使用另外两个下载选项,它们不是免费的。
说明 仿真器不支持依赖于硬件的特性,比如iPhone的加速计或摄像功能。要支持这些特性,需
要使用其他选项。
1.3 必备知识 3
标准版程序的价格为99美元。它提供了全面的开发工具、资源和技术支持,支持通过苹果公
司的App Store分发应用程序,并且最重要的是,支持在iPhone上(而不只是在仿真器上)测试和
调试代码。
企业版程序的价格为299美元,可供企业开发专用的、内部的iPhone和iPod Touch应用程序。
有关这两种程序的详细信息,请访问http://developer.apple.com/iphone/program/。
由于iPhone是一种始终连网的移动设备,并且使用的是其他公司的无线基础设施,因此苹果
公司对iPhone开发人员的限制比对Mac开发人员多得多,Mac开发人员无需经过苹果公司的审查
或批准就能够编写和分发程序。
苹果公司添加这些限制,更多的是为了尽量避免分发恶意或效率低下的程序,因为这类程序
可能降低共享网络的性能。开发iPhone应用程序似乎麻烦不少,但苹果公司在简化开发过程方面
付出了巨大努力。还应该提及的是,99美元的价格比微软公司的软件开发IDE——Visual Studio
的价格低得多。
另外,很明显,你还需要一部iPhone。虽然大部分代码都可以通过iPhone仿真器进行测试,
但并非所有程序都是如此。一些应用程序需要在实际的iPhone上进行全面测试,然后才能分发给
说明 如果要注册标准版或企业版程序,你应该立即注册。批准过程可能需要一些时间,并且
通过批准之后才能在iPhone或iPod Touch上运行应用程序。但是不必担心,前几章中的所
有项目以及本书中的大多数应用程序,都可以在iPhone仿真器上运行。
1.3 必备知识
学习本书应该具备一定的编程知识。你应该理解面向对象编程的基础知识,例如,了解对象、
循环和变量的含义,还应该熟悉Objective-C编程语言。SDK中的Cocoa Touch是本书使用的主要工
具,它使用的是Objective-C 2.0编程语言,但是如果不了解Objective-C语言的新增特性也没有关
系。我们将重点介绍要使用的2.0语言特性,并解释其工作原理和使用它的原因。
你还应该熟悉iPhone本身。就像在任何其他平台中编写应用程序一样,你需要熟悉iPhone的
各种特性,并了解iPhone界面以及iPhone程序的外观。
还不熟悉Objective-C?
如果你从未使用Objective-C编写过程序,那么以下资源有助于你了解该语言。
首先,阅读由Mac编程专家Mark Dalrymple和Scott Knaster撰写的Learn Objective-C on the
一书,该书浅显易懂,是学习Objective-C基础知识的优秀图书:
http://www.apress.com/book/view/9
① 中文版即将由人民邮电出版社出版。——编者注
4 第 1 章 欢迎来到 iPhone 的世界
接下来,访问Apple iPhone开发中心网站并下载The Objective-C 2.0 Programming Language
一书的电子版,该书深入浅出地介绍了Objective-C 2.0的方方面面,是一本优秀的参考指南:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC
注意,需要登录才能访问此文档。
1.4 编写 iPhone 应用程序有何不同
如果从未使用过Cocoa或它的前期产品NextSTEP,那么你可能会发现Cocoa Touch(用于编写
iPhone应用程序的应用程序框架)稍显另类。它与其他常用应用程序框架(如用于构建.NET或Java
应用程序的框架)之间存在一些基本差异。你起初可能会有点不知所措,但不必担心,只要勤加
练习,就可以掌握其中的规律。
如果你具备使用Cocoa或NextSTEP编程的经验,则会发现iPhone SDK中有许多熟悉的身影。
其中的许多类都是从用于Mac OS X开发的程序版本中原样借鉴过来的,一些类即便存在不同,
它们也遵循相同的基本原则,并使用类似的设计模式。但是,Cocoa和Cocoa Touch之间却存在一
无论你的知识背景如何,都需要谨记iPhone开发与桌面应用程序开发之间的重要差异。
1.4.1 只有一个正在运行的应用程序
除了操作系统之外,任何时候iPhone上都只能运行一个应用程序。随着iPhone内存的增大、
处理器的增强,这一点在未来可能会发生变化。但是在目前,在执行代码时,你的应用程序将是
唯一正在运行的程序。若你的应用程序不是用户正在交互中的,那么它不会起作用。
1.4.2 只有一个窗口
在桌面及笔记本操作系统中,多个程序可以同时运行,并且可以分别创建和控制多个窗口。
而iPhone则有所不同,它只允许应用程序操作一个“窗口”。应用程序与用户的所有交互都在这
个窗口中完成,而且这个窗口大小就是iPhone屏幕的大小,是固定的。
1.4.3 受限访问
计算机上的程序可以访问启动它们的用户能够访问的任何内容,而iPhone则严格限制了应用
程序的权限。你只能在iPhone为应用程序创建的文件系统中读写文件。此区域称为应用程序的沙
盒,应用程序在其中存储文档、首选项等需要存储的数据。
应用程序还存在其他方面的限制。举例来说,你不能访问iPhone上端口号较小的网络端口,
或者执行台式计算机中需要根用户或管理员权限才能执行的操作。
1.4.4 有限的响应时间
由于其使用方式特殊,iPhone及其应用程序需要具备较快的响应时间。启动应用程序之后,
1.4 编写 iPhone 应用程序有何不同 5
需要打开应用程序,载入首选项和数据,并尽快在屏幕上显示主视图,这一切要在几秒之内发生。
只要应用程序在运行,就可以从其下方拖出一个菜单条。如果用户按主页(home)按钮,iPhone
就会返回主页,并且用户需要快速保存一切内容并退出。如果未在5秒之内保存并放弃控制,则
应用程序进程将被终止,无论用户是否已经完成保存。
因此,你在设计iPhone应用程序时需要注意这一点,以确保用户退出时不会丢失数据。
1.4.5 有限的屏幕大小
iPhone的屏幕显示效果非常出色,从它推出直到现在,它一直是消费者设备上分辨率最高的
屏幕。但是,iPhone的显示屏幕并不大,你施展的空间要比现代计算机小很多,仅有480×320像
素。而在撰写本书时,苹果公司最便宜的iMac支持像素,最便宜的笔记本电脑MacBook
支持像素。而苹果公司最大的显示器,30英寸的Cinema Display,支持像素。
1.4.6 有限的系统资源
阅读本书的任何资深程序员可能都会对128 MB内存、4 GB存储空间的机器嗤之以鼻,因为
其资源实在是非常有限,但这种机器却是真实存在的。或许,开发iPhone应用程序与在内存为
48 KB的机器上编写复杂的电子表格应用程序不属于同一级别,二者之间没有可比性,但由于
iPhone的图形属性和它的功能,所以其内存不足是非常容易出现的。目前上市的iPhone具备128 MB
物理内存,当然这还会随时间不断增长。内存的一部分用于屏幕缓冲和其他一些系统进程。通常,
大约一半内存将留给应用程序使用。
虽然64 MB对于这样的小型计算机可能已经足够了,但谈到iPhone的内存时还有另一个因素
需要考虑:现代计算机操作系统,如Mac OS X,会将一部分未使用的内存块写到磁盘的交换文
件中。这样,当应用程序请求的内存超过计算机实际可用的内存时,它仍然可以运行。但是,iPhone
OS并不会将易失性内存(如应用程序数据)写到交换文件中。因此,应用程序可用的内存量将
受到电话中未使用物理内存量的限制。
Cocoa Touch提供了一种内置机制,可以将内存不足的情况通知给应用程序。出现这种情况
时,应用程序必须释放不需要的内存,甚至可能被强制退出。
1.4.7 缺少 Cocoa 工具
如果你在接触iPhone之前有过Cocoa方面的经验,那么你过去习惯使用的一些工具在iPhone
中已经不可用了。iPhone SDK不支持Core Data或Cocoa Binding。我们之前已经说过,Cocoa Touch
使用的是Objective-C 2.0,但该语言中的一个关键特性在iPhone中并不可用:Cocoa Touch不支持
垃圾收集。
1.4.8 新属性
前面已经说过,Cocoa Touch缺少Cocoa的一些功能,但iPhone SDK中也有一些新功能是Cocoa
所没有的,或者至少不是在任何Mac上都可用的。iPhone SDK为应用程序提供了一种定位方法,
6 第 1 章 欢迎来到 iPhone 的世界
即使用Core Location确定电话的当前地理坐标。iPhone还提供了一个内置的摄像和照片库,并且
SDK允许应用程序访问这两者。iPhone还提供了一个内置的加速计,用于检测iPhone的持有和移
1.4.9 与众不同的方法
iPhone没有键盘和鼠标,这意味着它与用户的交互方式与通用的计算机截然不同。所幸的是,
大多数交互都不需要你来处理。举例来说,如果在应用程序中添加一个文本字段,则iPhone知道
在用户单击该字段时调用键盘,而不需要编写任何额外的代码。
1.5 本书内容
下面是本书其余章节的简要概述。
第2章:讲述如何使用Xcode和Interface Builder创建一个简单的界面,并在iPhone屏幕上添加
一些文本。
第3章:开始实现与用户的交互,构建一个简单的应用程序,用于在运行时根据用户按下的
按钮动态更新显示的文本。
第4章:以第3章为基础,介绍其他一些iPhone标准用户界面控件。我们还将介绍如何使用警
告框和表提醒用户做出决策,或者通知用户发生了一些异常事件。
第5章:了解自动旋转机制,该机制允许在纵向或横向模式下使用iPhone应用程序。
第6章:介绍更多高级用户界面,并阐述如何创建多视图界面。我们将更改在运行时为用户
显示的视图,以创建更加复杂的用户界面。
第7章:介绍如何实现工具栏控制器,它是一个标准的iPhone用户界面。
第8章:介绍表视图。表视图是向用户提供数据列表的主要方法,并且是基于分层导航的应
用程序的基础。
第9章:介绍如何实现分层列表,它是最常用的iPhone应用程序界面之一,你可以通过它查
看更多或更详细的数据。
第10章:介绍如何实现应用程序设置,iPhone中的这种机制允许用户设置他们的应用程序级
第11章:介绍iPhone上的数据管理。我们将讨论如何创建用于保存应用程序数据的对象,以
及如何将这些数据持久存储到iPhone的文件系统和嵌入式数据库SQLite中。
第12章:绘图是人们的普遍爱好,这一章介绍如何实现一些自定义绘图,这需要使用Quartz
和OpenGL ES中的基本绘图函数。
第13章:iPhone的多点触摸屏幕可以接受用户的各种手势输入。这一章讲述如何检测基本的
手势,如双指捏合和单指滑动,还将介绍定义新手势的过程,并讨论新手势的适用情况。
第14章:iPhone可以通过Core Location确定其纬度和经度。这一章将编写利用Core Location
计算iPhone的物理位置的代码,并在各种应用中使用该信息。
1.6 准备开始吧 7
第15章:介绍如何与iPhone加速计交互,iPhone通过加速计确定其持有方式。我们将讨论应
用程序如何通过该信息完成一些有趣的任务。
第16章:每个iPhone都有自己的摄像设备和图片库,这两者都可供应用程序使用。这一章介
绍如何使用它们。
第17章:iPhone现已遍及70多个国家,这一章介绍以何种方式编写应用程序能方便地把所有
部分翻译为其他语言,从而发掘应用程序的潜在用户。
第18章:至此,你已经掌握了iPhone应用程序的基本构建方法。但接下来再应向何处去呢?
这一章将探索掌握iPhone SDK的后续步骤。
1.6 准备开始吧
iPhone是一款全新的、令人难以置信的计算平台,是轻松开发的利器。编写iPhone应用程序
将成为一种全新的体验,这种体验与之前你使用过的任何平台都不同。所有看似熟悉的功能都具
有其独特的一面,但随着深入体会本书中的代码,你将能把这些概念紧密联系起来并融会贯通。
应该谨记,本书中的练习并不是一份检验清单,似乎完成这些练习之后,你就自动具有了
iPhone开发专家的资格。在继续下一个项目之前,确保已经理解了这些概念和原理。不要害怕修
改代码。多多尝试并观察结果是在Cocoa Touch环境中克服编码困难的最佳方法。
如果你已经安装了iPhone SDK,请继续阅读本书。如果还没有,请立即安装iPhone SDK。然
后开始iPhone之旅!
144 第 8 章 表视图简介
表视图简介
一章将构建一个基于分层导航的应用程序,它类似于iPhone随带的电子邮件应用程序。
通过这个应用程序,用户可以访问数据嵌套列表和编辑数据。不过,在此之前,需要
先掌握表视图的基本概念。这正是本章将要介绍的内容。
表视图是用于向用户显示数据的一种最常见的机制。它们是高度可配置的对象,可以被配置
为用户所需的任何形式。电子邮件使用表视图显示账户、文件夹和消息的列表,但是表视图并不
仅限于显示文本数据。还可以在YouTube、Settings和iPod应用程序中使用表视图,尽管这些应用
程序具有十分不同的外观(参见图8-1)。
图8-1 虽然看起来各自不同,但Settings、iPod和YouTube应用程序都使用表视图来显示数据
8.1 表视图基础
表用于显示数据列表。数据列表中的每项都由行表示。iPhone表没有限制行的数量,其数量
仅受可用存储空间的限制。iPhone表可以只有一列。
表视图是显示表数据的视图对象,它是UITableView类的一个实例。表中的每个可见行都由
UITableViewCell类实现。因此,表视图是显示表中可见部分的对象,表视图单元负责显示表中
的一行(参见图8-2)。
8.1 表视图基础 145
图8-2 每个表视图都是UITableView的一个实例,每个可见行都是UITableViewCell的一个实例
表视图并不负责存储表中的数据。它们只存储足够绘制当前可见行的数据。表视图从遵循
UITableViewDelegate协议的对象获取配置数据,从遵循UITableViewDataSource协议的对象获得
行数据。本章稍后介绍的示例应用程序将展示如何实现这些操作。
如前所述,所有的表都只有1列。但是,图8-1右边所示的YouTube应用程序外观确实至少拥
有2列,如果数一数图标,甚至会发现原来有3列。不过情况并非如此。表中的每一行都由一个
UITableViewCell表示,可以使用一个图像、一些文本和一个可选的辅助图标来配置每个
UITableViewCell对象。其中辅助图标是指位于右边的一个小图标,下一章将对它进行详细的介
如果需要的话,可以在一个单元中放置更多的数据。可以通过两种基本方法来完成此操作。
一种方法是向UITableViewCell添加子视图;另一种方法是通过子类化UITableViewCell。你可以
按照任何喜欢的方式展示表视图单元,也可以添加任何想要的子视图。这样看来,单列限制并不
像开始听起来那样可怕。如果这些让你感到迷惑,别担心,本章稍后将介绍这方面的技巧。
分组表和索引表
表视图分为两种基本样式。第一种是分组表。分组表中的每个组都由嵌入在圆角矩形中的多
个行组成,如图8-3最左边的图片所示。注意,一个分组表可以只包含一个组。
另一种类型是索引表(在某些地方又称为无格式表)。索引表是默认的样式。任何没有圆角
矩形属性的表都是索引表视图。
如果数据源提供了必要的信息,通过表视图,用户可以使用右侧的索引来导航列表。图8-3
显示了一个分组表、一个不带索引的索引表(无格式表)和一个带有索引的索引表。
146 第 8 章 表视图简介
图8-3 相同的表视图分别显示为分组表(左)、不带索引的索引表(通常指无格式表,中间)、
和一个带有索引的索引表(右)
表中的每个部分被称为数据源中的分区(section)。在分组表中,每个分组都是一个分区(参
见图8-4)。在索引表中,数据的每个索引分组都是一个分区。例如,在图8-3所示的索引表中,以
“A”开头的所有名称都是一个分区,以“B”开头的那些名称则是另一个分区,依此类推。
图8-4 分组表中的分区和行显而易见,不过所有的表都支持分区和行
8.2 实现一个简单的表 147
分区主要有两个作用。在分组表中,每个分区表示一个组。在索引表中,每个分区对应一个
索引条目。因此,如果你希望显示一个按字母顺序列出索引且每个字母作为一个索引条目的列表,
那么你将拥有26个分区,每个分区包含以特定字母开头的所有值。
注意 从技术上来说,可以创建带有索引的分组表。即便如此,也不应该为分组表视图提供索
引。iPhone Human Interface Guideline(iPhone人性化界面指南)这本书中明确指出分组表
不应该提供索引。
在本章中,我们将创建这两种类型的表。
8.2 实现一个简单的表
下面通过一个最简单的示例来了解表视图的工作原理。本示例将显示一个文本值列表。
在Xcode中创建一个新项目。对于本章来说,我们将使用基于视图的应用程序模板。选择这
一项,然后将项目命名为Simple Table。
8.2.1 设计视图
展开Resources和Classes文件夹。这是一个极为简单的应用程序,它不需要任何输出口或操作,
双击Simple_TableViewController.xib,在Interface Builder中打开该文件。View窗口应该已经打开,
因此,只需要在库中找到Table View(参见图8-5),并将它拖到View窗口中即可。
表视图会自动将其高度和宽度调整为View窗口的高度和宽度(参见图8-6)。这正是我们所希
望的。将表视图设计为占据屏幕的整个宽度,以及除应用程序导航栏、工具栏或标签栏之外的高
图8-5 库中的表视图 图8-6 添加表视图之后的View窗口
将表视图拖到View窗口上之后,它应该仍然处于选中状态,如果不是,那么通过单击操作来
选定它,然后按下 打开连接检查器。你会注意到,表视图的前两个可用连接和选取器视图的前
两个连接一样,都是数据源和委托。从每个连接旁边的圆圈拖到File’s Owner图标。这样一来,
控制器类就成为此表的数据源和委托。完成上述操作之后,保存并关闭,然后返回到Xcode。
148 第 8 章 表视图简介
8.2.2 编写控制器
下面是控制器类的头文件。单击Simple_TableViewController.h,并添加以下代码:
上述代码的作用是让类遵从两个协议,类需要使用这两个协议来充当表视图的委托和数据
源,然后声明一个数组用于放置将要显示的数据。
现在切换到Simple_TableViewController.m,添加更多的代码:
8.2 实现一个简单的表 149
我们为控制器添加了3个方法。你可能对第一个方法ViewDidLoad感到很熟悉,因为我们前面
使用过类似的方法。此方法只创建了一个要传递给表的数据的数组。在实际应用程序中,此数组
很可能来自于另一个源,比如文本文件、属性列表或URL。
继 续 往 下 看 , 你 会 看 到 我 们 添 加 了 两 个 数 据 源 方 法 。 第 一 个 方 法 是 tableView:
numberOfRowsInSection:,表使用它来查看指定分区中有多少行。正如你所希望的,默认的分区
数量为1,此方法用于返回组成列表的表分区中的行数。只需返回数组中数组项的数量即可。
下一个方法可能需要一些解释,让我们更仔细地看一下此方法:
当表视图需要绘制其中一行时,则会调用此方法。你会注意到此方法的第二个参数是一个
NSIndexPath实例。表视图正是使用此机制把分区和行绑定到一个对象中的。要从NSIndexPath中
获得一行或一个分区,只需要调用行方法或分区方法就可以了,这两个方法都返回一个int值。
第一个参数tableView是对发起请求的表的引用。通过它,我们可以创建充当多个表的数据
下面,声明一个静态字符串实例。
此字符串充当表示某种表单元的键。在此表中,我们将只使用一种单元,因此定义一种标识
符就可以了。表视图在iPhone的小屏幕上一次只能显示几行,但是表自身能够保存相当多的数据。
记住,表中的每一行都由一个UITableViewCell实例表示,该实例是UIView的一个子类,这就意
味着每一行都能拥有子视图。对于大型表来说,如果视图为表中的每一行都分配一个表视图单元,
150 第 8 章 表视图简介
不管该行当前是否正被显示,这都将带来大量开销。幸好表并不是这样工作的。
相反,因滚动操作离开屏幕的一些表视图单元,将被放置在一个可以被重用的单元序列中。
如果系统运行比较慢,表视图就从序列中删除这些单元,以释放存储空间,不过,只要有可用的
存储空间,表视图就会重新获取这些单元,以便以后再次使用它们。
当一个表视图单元滚出屏幕时,另一个表视图单元就会从另一边滚动到屏幕上。如果滚动到
屏幕上的新行重新使用从屏幕上滚动下来的其中一个单元,系统就会避免与不断创建和释放那些
视图相关的开销。要充分利用此机制,我们需要让表视图给定一个出列单元,该出列单元正是我
们需要的类型。注意,我们现在正在使用前面声明的NSString标识符。实际上,我们需要一个
SimpleTableIdentifier类型的可重用单元:
现在,表视图中可能没有任何多余的单元了,我们来检查这些cell,看一下它是否为零(nil)。
如果是,则使用上面提到的标识符字符串手动创建一个新的表视图单元。从某种程度上来说,我
们将不可避免地重复使用此处创建的单元,因此需要确保它具有相同的类型。
现在,我们拥有了一个可以返回到表视图的表视图单元。下面所有要做的就是把需要显示的
信息放在该表视图单元中。在表的一行内显示文本是很常见的任务,因此表视图单元提供了一个
名称为text的属性,我们可以设置此属性以显示字符串。对于这种情况,我们需要从listData数
组中获取正确的字符串,然后使用它设置表视图单元的text属性。
要完成上述操作,需要知道表视图需要显示哪些行。可以从
indexPath变量获取该信息,如下所示:
我们使用这个值从数组获取正确的字符串,将它分配给单元的text
属性,然后返回该单元。
情况并不那么糟糕,对吗?下面编译并运行应用程序。等一下,是不
是有地方弄错了?出现了一个链接错误?你认为我们应该怎么做呢?
如果你被难住了,那么给你一个提示:我们使用了一个名为
CGRectZero的常量,它是Core Graphics框架的一部分。默认情况下,Core
Graphics框架没有连接到项目。如果你忘记如何将它连接进来的话,可
以参见第5章,其中逐步地介绍了此过程。解决这个问题后,就可以成
功完成编译了。运行应用程序,你将看到显示在表视图中的数组值(参见图8-7)。
图8-7 简单的表应用程序
8.4 附加配置 151
8.3 添加一个图像
要是可以向每一行添加一个图像就好了。我们需要创建一个UITableViewCell子类来添加图
像吗?不用。实际上,如果能够让图像位于每一行的左侧就不需要这么做了。默认的表视图单元
会把这个情况处理好。下面我们来看一看。
在项目归档文件的08 Simple Table文件夹中,找到名为star.png的文件,然后把它添加到项目
的Resources文件夹中。star.png是为此项目准备的一个小图标。
下 面 看 看 代 码 部 分 。 在 Simpe_TableViewController.m 文 件 中 , 在 tableView:cellFor-
RowAtIndexPath:方法中添加以下代码:
好,这就完成了。刚才我们把单元的image属性设置为想要显
示的任何图像。现在,如果编译并运行应用程序,出现的列表每
一行的左侧都有一个漂亮的小星星图标(参见图8-8)。当然,如
果愿意的话,可以为表中的每一行设置一个不同的图像。或者,
费些工夫,为所有行分别应用不同的图标。
8.4 附加配置
你会注意到我们使用控制器作为此表视图的数据源和委托,
不过到现在为止,还没有真正实现UITableViewDelegate的任何方
法。与选取器视图不同,较简单的表视图不需要委托代替它们完
成一些功能。数据源提供了绘制表所需要的所有数据。委托只是
用于配置表视图的外观并处理某些用户交互。现在,让我们看一
图8-8 使用单元的image属
性,为每个表视图
单元添加一个图像
152 第 8 章 表视图简介
下几个配置选项。下一章将更详细地介绍此内容。
8.4.1 设置缩进级别
可以使用委托指定缩进某些行。在Simple_TableViewController.m文件中,在代码中的@end
declaration上方添加以下方法:
此方法把每一行的缩进级别设置为其行号,所以第0行的
缩进级别为0,第1行的缩进级别为1,依此类推。缩进级别是
一个整数,它会告诉表视图把一行向右移动一点。缩进级别
的数量越大,行向右缩进得就越多。例如,可以使用这项技
术来表示一行从属于另一行,就好像在电子邮件中表示子文
件夹一样。
再次运行应用程序,可以看到每一行都在上一行的基础
上向右移动了一些距离(参见图8-9)。
8.4.2 处理行的选择
表的委托可以使用两个方法确定用户是否选择了特定的
行。一个方法在一行被突出显示之前调用,并且可以用于阻
止选中此行,甚至改变被选中的行。让我们来实现这个方法,
并 指 定 第 一 行 是 不 能 被 选 中 的 。 将 以 下 方 法 添 加 到
Simple_TableViewController.m的尾部,位于在@end声明之前:
这个方法获取传递过来的indexPath,它用于表示哪项将被选中。我们的代码着眼于哪一行
将被选中。如果这一行是第一行,其索引将始终为零,那么它将返回nil,表示实际上没有行被
图8-9 表中的每一行都比上一行
具有更高的缩进级别
8.4 附加配置 153
选中。否则,它返回indexPath,表示选择可以继续进行。
在编译和运行应用程序之前,我们还要实现委托方法,在一行被选中之后调用该方法,通常
它也是实际处理选择的地方。用户选中一行时,可以在这里做任何操作。在下一章中,我们将使
用此方法处理更深入的问题。本章将只使用此方法抛出一个警告以显示某一行被选中了。将下面
的方法添加到Simpe_TableViewController.m的尾部,位于@end声明之前。
添加此方法之后,编译并运行应用程序。看一下你是
否能够选中第一行(应该不能),然后选择其他行。被选
中的行应该会突出显示,然后弹出警告通知你选择的是哪
一行(参见图8-10)。
注意,你还可以在传递回indexPath之前修改索引路
径,这将导致不同的行和/或分区被选中。你不会经常这
样做,因为没有什么理由需要更改用户的选择。在大多数
情况下,使用此方法时将返回indexPath或nil,以允许或
禁止某个选择。
8.4.3 更改字体大小和行高
假设我们希望更改表视图中使用的字体大小。在大多
数情况下,不应该覆盖默认的字体,那是用户所希望看到
的 。 不 过 有 时 候 我 们 有 合 适 的 理 由 这 样 做 。 在
tableView:cellForRowAtIndexPath:方法中添加下面的
代码行,然后编译并运行:
图8-10 在本示例中,第一行是不可选的。
当选中其他任意行时会显示一
个警告。此功能是使用委托方法
154 第 8 章 表视图简介
现在运行应用程序,列表中的值会变得很大,但是它们的大小并不适合行(参见图8-11)。
好,现在靠表视图委托来援救吧!表视图委托可以指定表中的行高。实际上,如果需要的话,
它可以为每一行指定唯一值。下面向控制器类中添加此方法,代码位于@end之前。
在上面的代码中,我们使表视图把所有行高都设置为行180像素。编译并运行应用程序,现
在表中的行应该高多了(参见图8-12)。
图8-11 大字体效果不错!不过如果我们
能看见所有内容就更好了
图8-12 使用委托更改行大小。太大了吗?
8.5 定制表视图单元 155
8.4.4 委托还能做什么?
委托还能处理更多任务,下一章在介绍分层数据时会用到这些任务中的大多数。要了解更多
内容,请使用文档浏览器查看UITextViewDelegate协议,然后看一下还有什么可用的其他方法。
8.5 定制表视图单元
你可以直接为表视图做许多事情,不过一般来说,你会希望以不受UITableViewCell直接支
持的方式格式化每一行中的数据。对于这种情况,可以采用两种基本方法。一种方法是向
UITableViewCell添加子视图,另一种方法是创建一个UITableViewCell子类。下面我们来看一下
这两种方法。
8.5.1 单元应用程序
要展示如何使用自定义单元,我们将创建一个新的应用
程序,使用另一个表视图,然后向用户显示两行信息(参见
图8-13)。应用程序将显示一系列常见计算机模型的名称和颜
色。通过向表视图单元添加子视图,我们将在同一个表单元
中显示这两组信息。
8.5.2 向表视图单元添加子视图
默认的表视图单元只显示一行文本。即使你试图通过指
定一个包含回车符的字符串让单元显示多个行,它也会删除
回车符,并在下一个单元的行中显示数据。现在我们要创建
一个项目,向单元添加子视图以摆脱这种束缚,这样就可以
在每个单元中显示两行数据。
使用基于视图的应用程序模板创建一个新的Xcode项目,
将它命名为Cells。双击CellsViewController.xib,添加一个Table
View,然后像我们在上一章所做的,把委托和数据源设置为
File’s Owner。保存并回到Xcode。如果需要,可以参考8.6.1节的内容。
1. 修改控制器头文件
单击CellsViewController.h,添加以下代码:
图8-13 向表视图单元添加子视图,
可以让一个单元支持多行
156 第 8 章 表视图简介
你首先会注意到这里我们定义了两个常量。我们稍后将使用这两个常量为将要添加到表视图
单元中的子视图分配标记(tag)。下面将向一个单元中添加4个子视图,其中2个需要在每一行进
行更改。为此,需要在使用特定的行数据更新单元时,通过某种机制检索单元中的两个字段。如
果为需要再次使用的每个标签设置唯一的标记值,那么将能够从表视图单元检索它们并设置它们
2. 实现控制器代码
在控制器中,我们需要设置要用到的一些数据,然后通过实现表数据源方法将这些数据反馈
给表。单击CellsViewController.m,然后添加以下代码:
8.5 定制表视图单元 157
158 第 8 章 表视图简介
在这里,viewDidLoad方法创建了一系列字典。每个字典都包含表中一行的名称和颜色信息。
某一行中的名称在字典的Name键下,颜色在Color键下。我们把所有的字典放到了同一个数组里,
这就是此表的数据。
让我们着重看一下tableView:cellForRowWithIndexPath:,此方法中真正添加了新内容。代
码的前两行像前面介绍过的一样,先创建一个标识符,然后,如果表提供了出列的表视图单元,
则要求表将该单元退出队列。
如果表没有任何可以重用的单元,就必须创建一个新的单元。创建新单元时,还需要创建和
添加将要用到的子视图,以实现每单元两行的表。让我们更仔细地研究一下代码。首先,创建一
个单元,其实这跟前面一样,除非不使用表视图进行计算,而是手动指定单元的大小。
接下来需要创建4个UILabel,并把它们添加到表视图单元。表视图单元已经有了一个名为
contentView的UIView子视图,用于对它的所有子视图进行分组,就像第4章中我们对UIView中的
两个开关进行分组一样。因此,我们不用把标签作为子视图直接添加到表视图单元,而是添加到
contentView。
其中两个标签包含静态文本。NameLabel标签包含Name:文本,colorLabel标签包含Color:文
本。这些是不需要更改的静态标签。另两个标签用于显示指定行的数据。记住,稍后我们需要检
索这些字段,所以要为这两个字段分配值。例如,把常量kNameValueTag分配给nameValue的tag
8.5 定制表视图单元 159
稍后,我们将使用该标记从单元中检索正确的标签。
创建新单元之后,使用传入的indexPath参数确定表正在请求单元的哪一行,然后使用该行
的值为请求的行获取正确的字典。记住,该字典有两个键/值对,一个是名称,一个是颜色。
还记得我们前面设置的标记吗?在这里,我们使用那些标记检索需要设置值的标签。
检索到标签以后,只需将标签文本设置为从表示此行的字典里获取的一个值。
编译并运行应用程序,你会得到带有两行数据的行,如图8-13所示。向表视图添加视图比单
独使用标准的表视图单元具有更大的灵活性,不过,通过编程创建、定位和添加所有的子视图是
一项单调乏味的工作。如果我们能在Interface Builder中设计表视图单元就好了,不是吗?
8.5.3 使用 UITableViewCell 的自定义子类
我们很幸运,可以使用Interface Builder设计表视图单元。我们将使用Interface Builder重新创
建与刚才使用代码构建的界面相同的两行界面。要达到此目的,可以创建一个UITableViewCell
子类和一个包含表视图单元的新nib文件。然后,当我们需要一个表视图单元来表示一行时,不
是向标准的表视图单元添加子视图,而是从nib文件加载子类,并使用将添加的两个输出口来设
置名称和颜色。有道理吗?让我们开始付诸行动吧。
在Xcode中右键单击(或Ctrl+单击)Classes文件夹,从出现的Add子菜单中选择New File…,
或者按下 键。新建文件向导出现后,从左侧窗格选择Cocoa Touch Classes,然后从右上窗格选
择UITableViewCell子类。单击Next按钮,将新文件命名为CustomCell.m,并确保选中了Also Create
“CustomCell.h”复选框。
创建文件之后,在Xcode中右键单击Resources文件夹,再次选择Add→New File…。这一次,
在新建文件向导的左侧窗格中单击User Interfaces,在右上窗格中选择Empty XIB。当提示输入名
称时,输入CustomCell.xib。
1. 创建UITableViewCell子类
创建所有必要的新文件之后,下面让我们继续创建UITableViewCell的新子类。
我们将在子类中使用输出口,这会简化对需要在每一行更改的值的设置。我们可以再次使用
标记(tag),这完全避免了创建子类,而使用这种方式,代码会更加简明并容易阅读,因为我们
可以仅通过设置属性来设置每一行单元上的标签,如下所示:
单击CustomCell.h,添加以下代码:
160 第 8 章 表视图简介
这就是我们需要添加的所有内容,下面切换到CustomCell.m,并添加两行代码:
保存上面的代码,并准备好自定义子类。
2. 在Interface Builder中设计表视图单元
下一步,双击CustomCell.xib,在Interface Builder中打
开文件。这个主窗口中只有两个图标:File’s owner和First
Responder。在库中找到表视图单元(参见图8-14),然后
把它拖动到主窗口中。
确保选中了表视图单元,然后按下 ,打开标识检查
器。将类从UITableViewCell改为CustomCell。
然后,按下 ,打开大小检查器,将表视图单元的高
度从44改为65。这会让我们有更多的活动空间。
最后,按下 ,打开属性检查器。其中第一个字段是 图8-14 库中的表视图单元
8.5 定制表视图单元 161
Identifier,它是我们在代码中使用过的可重用的标识符。如
果 记 不 起 来 这 一 内 容 , 请 查 阅 本 章 前 面 的 内 容 并 找 到
SimpleTableIdentifier 。 将 Identifier 设 置 为 CustomCell-
Identifier。下一步,找到名称为Accessory的弹出按钮,把
Detail Discloure改为None(参见图8-15)。扩展图标会在单元中
占用一些空间,但是我们希望整个单元空间都归自己所用。下
一章将详细地讨论扩展图标。
记住,即使UITableViewCell是UIView的子类,它仍然使用
内容视图对子视图进行保存和分组。双击Custom Cell图标,将
打开一个新的窗口,你会发现一个标记为Content View的灰色
虚线圆角矩形(参见图8-16)。
Interface Builder通过这种方式告诉你应该添加一些内容,
因此在库中找到View并把它拖到Custom Cell窗口中。
发布视图之后会发现它的大小和窗口大小不一致,还要进
行调整。选中新的视图,打开大小检查器。通过将x设置为0,
y设置为0,w设置为320,h设置为65,把View的大小和位置改
为符合Custom Cell窗口的大小。
现在所有项都设置完成了。我们有了一个画布,可以使用
它在Interface Builder中设计表视图单元。下面就开始吧。
从库中拖动4个标签到Custom Cell窗口,按照图8-17所示进
行布局和重命名。要将Name:和Color:设置为黑体,选中它们
并按下 。下一步,选中右上方的标签,增加其宽度,将其右
边缘拖到右边的蓝线。按同样方式更改右下位置的标签。这样
做的目的是让名称和颜色数据拥有更大的显示空间。
现在,按下Control键,并将Custom Cell图标拖到视图右上
位置的标签,为它指定nameLabel输出口。然后,按下Control
键,把Custom Cell图标再次拖到右下位置的标签,为它指定
colorLabel输出口。
你可能很奇怪为什么我们没有做任何和File’s Owner图标
有关的事情。原因是根本不需要。我们使用这个表单元显示数
据,不过与用户的所有交互都是通过表视图来完成的,因此它
不需要自己的控制器类。我们实际上只是使用nib作为一种模板,以便可视地设计表单元。
保存nib并将其关闭,然后返回Xcode。
3. 使用新的表视图单元
要 使 用 我 们 设 计 的 单 元 , 必 须 对 CellsViewController.m 中 的 talbeView:cellForRow-
AtIndexPath方法做一些大的改动。删除当前的talbeView:cellForRowAtIndexPath方法,用下面
图8-15 关闭扩展图标
图8-16 表视图单元的窗口
图8-17 表视图单元的设计
162 第 8 章 表视图简介
的新版本代替:
更改CellsViewController.m时,在接近顶部的位置添加此行:
由于我们在nib文件中设计了表视图单元,因此,如果没有可重用的单元,只需从nib文件中
加载即可。我们在objectAtIndex:调用中使用索引值1而不是0,因为对象0是文件的所有者,它
并不是我们想要的。First Responder不是由loadNibNamed:owner:options:返回的,因此表视图单
元的索引值为1。
下面还要添加另一项内容。由于更改了表视图单元默认的高度值,我们必须告知表视图这一
事实;否则,表视图单元不会留下足够的显示空间。为此,在CellsViewController.m中添加以下
委托方法,将其添加到@end之前:
然后,我们不能从单元获得这个值,因为此委托方法可能在单元存在之前被调用,因此我们
必须硬编码这个值。把这个常量定义添加到CustomCell.h的顶部,然后删除那些不再需要的tag
这就好了。编译并运行程序。现在,两行的表单元都是基于Interface Builder设计技术的。
8.6 分组分区和索引分区 163
8.6 分组分区和索引分区
下一个项目将探讨表的另一个基本内容。仍然使用一个
表视图(没有分层),不过我们将把数据分为几个分区。再次
使用基于视图的应用程序模板创建一个新的Xcode项目,这一
次将它命名为Sections。
8.6.1 构建视图
打开Classes和Resources文件夹,在Interface Biulder中双
击SectionsViewController.xib,打开文件。与之前一样,把表
视图拖到View窗口中。然后按下 ,将数据源和委托连接到
File’s Owner图标。
下一步,确保选中表视图,按下 ,打开属性检查器。
把表视图的Style从Indexed改为Grouped(参见图8-18)。这里
可以提示一下,我们在本章开头讨论过索引类型和分组类型
之间的差别。保存并返回Xcode。
8.6.2 导入数据
要完成此项目需要大量的数据。我们提供了另一个属性
列表,为你节省几个小时敲键盘的时间。从本书随附的项目归档文件的08 Sections文件夹中找到
名为sortednames.plist文件,把它添加到项目的Resource文件夹中。
完成添加以后,单击sortednames.plist,看一下它到底是什么(参见图8-19)。它是包含字典的一
个属性列表,其中字母表中的每个字母都有一个条目。每个字母下面是以该字母开头的名称列表。
图8-19 sortednames.plist属性列表文件
图8-18 表视图的属性检查器
164 第 8 章 表视图简介
我们将使用这个属性列表中的数据填充表视图,并为每个字母创建一个分区。
8.6.3 实现控制器
单击SectionsViewController.h文件,添加NSDictionary和NSArray实例变量及其相应的属性声
明 。 字 典 将 保 存 所 有 数 据 。 数 组 将 保 存 以 字 母 顺 序 排 序 的 分 区 。 还 需 要 让 类 遵 循
UITableViewDataSource和UITableDelegate协议:
现在,切换到SectionsViewController.m,并添加以下代码:
8.6 分组分区和索引分区 165
166 第 8 章 表视图简介
上面的大部分代码和我们以前看到的没有多大区别。在viewDidLoad方法中,从添加到项目
的属性列表中创建了一个NSDictionary实例,并为它指定名称names。然后,获取字典中的所有
键,按照字典中字母表的顺序对键值进行排序,将会得到一个有序的NSArray。记住,NSDictionary
使用字母表中的字母作为它的键,因此这个数组将拥有26个字母,按照顺序从A到Z。我们将通
过这个数组来了解分区。
下面看一下数据源方法。我们添加的第一个方法指定了分区的数量。上次没有实现此方法是
因为默认设置1已经很合适了。这一次,我们需要告诉表视图字典中的每个键都有一个分区。
第二个方法用于计算特定分区中的行数。上一次,只有一个分区,所以只返回数组中拥有的
行数。这次,我们将以分区为单位返回行数。可以检索对应于正被考虑的分区的数组,并从该数
组返回行的数量,从而达到目的。
在tableView:cellForRowAtIndexPath:方法中,必须从索引路径获取分区和行,用它们来确
定要使用哪一个值。分区会告诉我们从名称字典中取出哪个数组,然后可以使用行指出要使用该
数组中的哪个值。方法中的其他内容基本上和Simple Table应用程序代码中的相同。
可以通过TalbeView:titleForHeaderInSection方法为每个分区指定一个可选的标题值,然
后只返回这一组的字母就可以了。
最后,由于在SectionViewController.m中引用了CGRectZero,我们需要连接到Core Graphics
框架。单击Groups & Files窗格中的Frameworks文件夹,从Project菜单中选择Add to Project。如
果你忘记了如何导航到框架,请返回到第5章的末尾部分,该部分详细介绍了框架的位置。
现在可以编译并运行项目,然后慢慢地欣赏它了。记住,我们已经把表的样式改为Grouped
8.6 分组分区和索引分区 167
了,因此最终拥有一个带有26个分区的分组表,如图8-20所示。
作为比较,让我们把表视图再次改为索引风格,然后看一下带有多个分区的索引表视图是什
么样子。在Interface Builder中双击SectionViewController.xib,打开该文件。选中表视图,使用属
性检查器将视图改为Indexed。保存并返回Xcode,编译并运行,得到的是相同的数据和不一样的
外观(参见图8-21)。
8.6.4 添加索引
当前表的一个问题是行数太多了。此列表中有2000个名称,要找到Zacharian或Zebedian,你
的手指会非常累,更别说Zojirishu了。
这个问题的一个解决方案是,在表视图的右侧添加一个索引。既然我们已经把表视图样式改
成了索引类型,要添加一个索引相对来说也很容易。在SectionsViewController.m文件尾部,@end
前面添加如下方法:
这就完成了。在这个方法中,委托请求一个值数组在索引中显示。必须使表视图中的多个分
区使用索引,而且此数组中的条目必须对应于这些分区。返回的数组拥有的条目数必须与拥有的
分区数相同,且值必须对应于适当的分区。也就是说,此数组中的第一项带给用户的是第一个分
区,即分区0。
再次编译并运行,你将得到一个很好的索引(参见图8-22)。
图8-20 有多个分区的分组表 图8-21 带有分区的索引表视图 图8-22 带有一个索引的索引表视图
168 第 8 章 表视图简介
8.7 实现搜索栏
索引是很有用的,即便如此,此处我们仍然有非常多的名称。例
如,如果要查看名称Arabella是否存在于列表中,使用索引之后仍然
需要拖动滚动条。如果能够通过指定搜索项简化该列表就好了,对不
对?这样对用户更友好。那只是一点额外的工作,并不是特别糟糕。
我们将实现一个标准的iPhone搜索栏,如图8-23所示。
8.7.1 重新考虑设计
在我们开始着手做之前,需要考虑一下应用程序是如何工作的。
当前,我们拥有一个包含多个数组的字典,其中字母表中的每个字母
都占有一个数组。该字典是不可改变的,这就意味着不能从字典添加
或删除值,它包含的数组也是如此。当用户取消搜索或者更改搜索项
时,还必须能够返回到源数据集。
我们能做的就是创建两个新的字典:一个包含完整数据集的不可
改变的字典、一个可以从中删除行的可变的字典副本。委托和数据源
将从可变字典进行读取,当搜索标准更改或者取消搜索时,可以从不
可改变的字典刷新可变字典。听起来像个好计划,下面就开始吧。
注意 下一个项目有些复杂,阅读得太会快让你感到有些不知所措。如果某些概念让你感到头
疼,请查阅Mark Dalrymple和Scott Knaster所著的Learn Object-C(Apress,2009),阅读此
书中与类别和易变性有关的内容。
8.7.2 深层可变副本
现 在 存 在 一 个 问 题 , NSDictionary 遵 循 NSMutableCopying 协 议 , 该 协 议 返 回 一 个
NSMutableDictionary,但是这个方法创建的是浅副本。也就是说,调用mutableCopy方法时,它
将创建一个新的NSMutableDictionary对象,该对象拥有源字典所拥有的所有对象。它们并不是
副本,而是相同的实际对象。如果我们所处理的字典仅存储字符串,这会很好,因为从副本中删
除一个值不会对源字典产生任何影响。然而,由于字典中存有数组,如果我们从副本的数组中删
除对象,这些对象也将从源字典的数组中被删除,因为副本和源都指向相同的对象。
要解决这一问题,需要为存有数组的字典创建一个深层可变副本。这并不难,不过我们应该
把这项功能放在哪儿呢?
如果你说“在类别中”,那么好极了,你的想法是正确的。如果还没有想到,别担心,习惯
这种语言需要花费一定的时间。通过类别可以向现有对象添加附加方法,而不需要子类化这些对
象。类别经常会被Objective-C的新手忽略,因为这些特性是大多数其他语言所没有的。
通过类别,我们可以向NSDitionary添加一个方法来实现深层副本,返回的NSMutable-
图8-23 带有搜索栏的
8.7 实现搜索栏 169
Dictionary拥有相同的数据,但不包含相同的实际对象。
在项目窗口中,选择Classes文件夹,然后按下 创建一个新文件。向导出现之后,从最底
端的左侧选择Other。然而,类别没有文件模板,我们要创建几个空文件来保存它。选择Empty File
图标,将第一个文件命名为NSDdictionary-MutableDeepCopy.h。重复此过程,将第二个文件命名
为NSDdictionary-MutableDeepCopy.m。
提示 创建类别所需的两个文件的一个更快的方法就是,选择NSObject子类模板,然后删除文
件内容。此选项将同时提供头文件和实现文件,为你省了一步。
将下面的代码添加到NSDdictionary-MutableDeepCopy.h中:
切换到NSDdictionary-MutableDeepCopy.m,并添加以下实现:
此方法创建一个新的可变字典,然后在源字典中的所有键中进行迭代,为它遇到的每个数组
创建可变副本。由于此方法将表现得好像它是NSDictionary的一部分,所以对self的任何引用都
是对调用到此方法上的字典的一个引用。此方法首先尝试创建深层可变副本,如果对象没有响应
mutableDeepCopy消息,那么它将尝试创建可变副本,如果对象没有响应mutableCopy消息,它就
170 第 8 章 表视图简介
回过头再创建常规副本,以确保对字典中包含的所有对象都创建了副本。通过这种方式,如果我
们有一个包含字典(或支持深层可变副本的其他对象)的字典,则也将对所包含的内容创建深层
对于大多数读者来说,这可能是第一次在Objective-C中看到如下语法:
Objective-C 2.0还有一种新特性,叫做快速枚举。快速枚举是NSEnumerator的语言级替代,
《Learn Objective C》一书对它进行了介绍。可以通过快速枚举对集合(如NSArray)进行迭代,
从而避免了创建附加对象的麻烦。
所有已交付的Cocoa集合类,包括NSDctionary、NSArray和NSSet,都支持快速枚举。而且可
以在任何需要的时候使用此语法对集合进行迭代。它将确保你获得效率最高的循环。
你可能注意到了,我们正在使用一个便利类方法创建ret字典,虽然我们以前曾警告过不要
使用不必要的便利方法。使用便利方法的问题是,由便利方法返回的对象被放到自动释放池,并
至少要等待当前事件循环结束,即使它的保留计数下跌到零。很显然,这里的问题是内存的低使
在这种情况下,当方法结束后返回值时,必须在该方法上调用autorelease,以确保它依然
为调用此方法的代码而存在。因为不管怎么样,它也要到自动释放池中,我们可以利用便利方法,
省去了键入一行或两行代码的工作。
如果在其他类中包含NSDictionary-MutableDeepCopy.h头文件,我们将能够在任何喜欢的
NSDictionary对象上调用mutableDeepCopy。现在让我们使用这一功能。
8.7.3 更新控制器头文件
下一步,我们需要向控制器头文件添加一些输出口。表视图需要一个输出口。目前为止,我
们还没有用到数据源方法之外指向表视图的指针,现在就需要一个,因为我们需要根

我要回帖

更多关于 c 资源文件 的文章

 

随机推荐