创建用于 iPad 的 iOS 幻灯片应用程序

使用 XML、XCode 和 iOS API

按照本文所述流程逐步学习创建 iOS 幻灯片应用程序。示例应用程序将与 Web 服务器通信,以检索 XML 幻灯片定义并显示幻灯片中包含的图像。

Jack D. Herrington, 资深软件工程师, Leverage Software Inc.

Jack Herrington 的照片Jack D. Herrington 是一名高级软件工程师,具有 20 多年的工作经验。他撰写过三本书:Code Generation in ActionPodcasting HacksPHP Hacks,还撰写了 30 多篇文章。



2012 年 1 月 04 日

简介

常用缩写词

  • IDE:集成开发环境
  • iOS:苹果的移动操作系统
  • OS X:苹果用于 Macintosh 计算机的操作系统

为 iOS 设备如 iPad 或 iPhone 编写应用程序是非常受欢迎的活动,这毫不奇怪。这些设备华丽且易于使用。这些设备拥有数百万的用户,为这些设备开发应用程序利润可观。人们喜欢在 iPad 和 iPhone 靓丽的屏幕上观看自己的照片。

在本文中,我们将学习如何从头开始创建 iOS 照片幻灯片应用程序。您要将一些 XML 代码和照片放在服务器上,创建 iOS 应用程序,添加一个图像视图,获取 XML,并制作幻灯片动画。

创建后端

示例幻灯片应用的后端实际上只是一个 XML 文件,您可以将其放在服务器上。清单 1 显示了示例 XML 以及一些示例图像。

清单 1. photos.xml
<photos>
<photo url="http://localhost/photos/CRW_0675.jpg" />
<photo url="http://localhost/photos/CRW_1488.jpg" />
<photo url="http://localhost/photos/CRW_3273.jpg" />
<photo url="http://localhost/photos/CRW_3296.jpg" />
<photo url="http://localhost/photos/CRW_3303.jpg" />
<photo url="http://localhost/photos/CRW_3359.jpg" />
<photo url="http://localhost/photos/CRW_3445.jpg" />
<photo url="http://localhost/photos/CRW_3752.jpg" />
<photo url="http://localhost/photos/CRW_3754.jpg" />
<photo url="http://localhost/photos/CRW_4525.jpg" />
<photo url="http://localhost/photos/CRW_4547.jpg" />
<photo url="http://localhost/photos/CRW_4700.jpg" />
<photo url="http://localhost/photos/CRW_4860.jpg" />
</photos>

这个 XML 非常简单。<photos> 标记包含多个 <photo> 标记。每个 <photo> 标记包含您想显示的图像的 URL。该 URL 必须完全合格和绝对;客户端应用程序将直接加载该 URL,而不是通过处理相对 URL 的任何类型的浏览器。

要完成后端,请修改该 XML 来包括对您的照片的引用,并将该 XML 加载到您的服务器上的一个已知的位置。如果一切都按计划进行,那么您应该能够浏览到该 XML,使用 Safari 执行(或您选择的任何浏览器),并看到 图 1 所示的内容。

图 1. 服务器上的 XML
浏览器中 XML 文件(清单 1)的屏幕截图

图 1 显示了 清单 1 中的 XML 为文本格式。每个浏览器的结果都不同,因为这只是一个简易的 XML(浏览器之间没有标准)。

要验证这些 URL 是否正确:

  1. 选择其中一个 URL。
  2. 将其复制并粘贴到浏览器的 URL 区域。
  3. Rreturn 键。

您应看到与 图 2 相似的内容。

图 2. 服务器上的一张照片
样例照片 CRW_1488.jpg 的屏幕截图,显示年轻女孩的面庞

位于服务器的一张照片被 XML 中的一个 URLs 引用。如果您没有看到该 XML,或者没有看到照片,那么您需要检查您的 Web 服务器配置和您的 URL。如果您在浏览器中无法看到照片,那么您的新 iOS 应用程序也无法看到照片。


创建客户端幻灯片应用程序

在配置完服务器并上传了照片后,您就可以开始创建 iOS 应用程序。第一步是安装 Apple Developer 工具(参见 参考资料 中的链接)。如果:

  • 您是 Pre-Lion,那么您需要从 Apple Developer 网站下载开发工具(参见 参考资料 中的链接)。
  • 您是 Running Lion,那么您可以使用 Mac App Store 下载这些工具(参见 参考资料 中的链接)。

在安装了开发工具后,运行 XCode 环境,它是 Apple 用于开发 iOS 和 Mac OS X 的 IDE。从 XCode 环境中,选择 New Project 的菜单选项。您应该看到应用程序向导的第一页,您将使用该应用程序的向导创建 iOS 或 Mac OS X 应用程序,如 图 3 所示。

图 3. 应用程序向导
为新项目选择模板的页面的屏幕截图

您可以从多个不同的应用模板进行选择。对于该示例,选择 View-based Application,然后单击 Next。 您应看到向导的最后一页,如 图 4 所示。

图 4. 项目选项
为新项目选择选项的页面的屏幕截图

在向导的第二页,命名您的应用程序并选择默认的设备系列(iPad 或 iPhone)。该示例应用程序的 “项目名称” 为 slideshow。Company Identifier 字段的值表示应用程序位于 com.jherrington 命名空间。(当然,您可以选择您喜欢的任何名称和公司标识。)为 Device Family(设备系列)选择 iPad,然后点击 Next

项目创建完成。此时,最好选择界面左上角的较大的 Play 按钮,从而首次运行您的应用程序。这一步骤编译了所有内容并引入了 iPad 模拟器。


添加图像视图

下一步是添加图像视图用于显示图像。iOS 框架提供了一套丰富的内置控件,可用来创建您的应用程序。对于该示例,您将使用 UIImageView 控件。通过使用 UIImageView 您可以显示那些编译到应用程序的图像,本地存储在设备中的图像,或者,如该示例所示,从网站下载的图像。

要添加 UIImageView,请打开 slideshowControllerView.XIB 文件,它是 slideshowControllerView 的用户界面定义文件。打开 XIB 后,请在对象面板选择 Image View,如 图 5 所示。

图 5. 将 UIImageView 对象添加到视图控制器 XIB
所选择的 Image View 选项的屏幕截图

选择了 Image View 后,将其拖放到 slideshowControllerView。通常,IDE 会自动缩放控件的尺寸,使其适应可用的空间。如果没有进行缩放,则只须拖动控件并调整其大小,直到它填满了整个显示区域。

当该控件出现在视图上后,设置某些参数获得应用程序的最佳外观和感受。图 6 显示了 Image View 控件的属性屏幕上的设置。

图 6. 配置 UIImageView
Image View 控件的属性屏幕的截图

您需要执行的两个修改分别是 “模式” 和 “背景”。将 “模式” 设置为 Aspect Fit,以便缩放该图像但仍保留其原始的宽高比。如果您不想使用 Aspect Fit,您的图像将拉伸和缩放,以匹配图像视图的显示区域,最终看起来非常棒。

由于图像可能并不总是适合可用的区域,您还需要将 Background 属性设置为 Dark Text Color 或使用颜色选择器选择深黑色。在默认情况下,该值为白色。大多数照片当放在亮白框架里时效果都不好。

保存 XIB 文件,并移动到 SlideshowViewController.h 文件。进行小改动,如 清单 2 所示。

清单 2. SlideshowViewController.h
#import <UIKit/UIKit.h>

@interface slideshowViewController : UIViewController {
    IBOutlet UIImageView *imgView;
}

@end

您需要将 Outlet 添加到 slideshowViewController,以允许在 XIB 中定义的控件连接到视图控制器类。

在添加了出口后,返回到 XIB 文件,选择 UIImageView,使用连接检查器将 UIImageView 对象连接到 slideshowViewController 类中的 imgView 变量。

连接完成后,对幻灯片视图控制器类本身进行代码修改,以加载图像。清单 3 显示了该类别的完整的第一版。

清单 3. SlideshowViewController.m
#import "slideshowViewController.h"

@implementation slideshowViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *imageURL = [NSURL URLWithString:@"http://localhost/photos/CRW_0675.jpg"];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    [imgView setImage:image];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:
   (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

slideshowViewController 类中的重要工作是以 viewDidLoad 方法完成的,现在:

  • 加载来自 URL 的数据。
  • 将数据转换成图像。
  • 在图像视图上使用 setImage 方法显示该图像。

此时,您应该运行该应用程序来测试图像是否会出现。您会看到与 图 7 相似的内容,该图显示了 iPad 模拟器中显示图像。

图 7. 来自服务器的第一个图像
浏览器中显示图像(女孩的面庞)的屏幕截图

如果您没有看到图像,问题很可能是因为 setImage 方法调用 imgView。验证 UIImageView 对象是否正确地连接到 imgView 变量。如果在此之前,应用程序发生了故障,那么您的 URL 可能不正确,或者服务器上的某些项目不正确。


解析 XML

现在您有方法显示 iPad 上的图像,下一步是加载 XML 获得要显示的所有图像的列表。iOS 框架拥有内置的 XML 解析器,因此,您只需要创建解析器对象并聆听各种标记的回调。

通过 NSXMLParserDelegate 接口扩展类本身,这会告知 iOS 框架该类能够从 XML 解析器接收回调。您还需要添加一个称为 photos 的阵列,该阵列保存了从 XML 中提取的 URL 列表。清单 4 显示了更新情况。

清单 4. 附带照片的 SlideshowViewController.h
#import <UIKit/UIKit.h>

@interface slideshowViewController : UIViewController<NSXMLParserDelegate> {
    IBOutlet UIImageView *imgView;
    NSMutableArray *photos;
}

@end

如果编写更多的 iOS 应用程序,您将发现您会使用越来越多的指令来连接到各种 API。还存在针对表格的回调、UI 元素 、GPS 回调等。您甚至能够为您自己的库创建自己的自定义接口。

要使用 XML 解析器,请扩展视图控制器类,如 清单 5 所示。

清单 5. 附带照片的 SlideshowViewController.m
- (void)viewDidLoad
{
    [super viewDidLoad];

    photos = [[NSMutableArray alloc] init];

    NSXMLParser *photoParser = [[[NSXMLParser alloc] 
       initWithContentsOfURL:
       [NSURL URLWithString:@"http://localhost/photos/index.xml"]] autorelease];
    [photoParser setDelegate:self];
    [photoParser parse];

    NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:0]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    [imgView setImage:image];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
   attributes:(NSDictionary *)attributeDict { 
    if ( [elementName isEqualToString:@"photo"]) {
        [photos addObject:[attributeDict objectForKey:@"url"]];
    }
}

该类以 viewDidLoad 方法创建了一个解析器,并使它请求并解析来自服务器的 XML。它还为解析器设置回指令,从而得到回调。

在该示例中,您想要监听每当遇到标记时都会触发的 didStartElement 回调。didStartElement 函数查看标记名称是否为照片标记。如果是的话,didStartElementurl 属性的值添加到照片阵列。

在完成了照片阵列后,viewDidLoad 方法会继续并将图像设置为阵列中的第一个图像。

运行该应用程序来测试您的进度。您应看到在 XML 中指定的第一个图像出现在模拟器中。如果您没有看到第一个图像,那么服务器上的 XML 可能有问题。在 didStartElement 方法中设置一个断点,查看它是否被调用。如果没有,那么您不会从服务器获取任何有效的 XML。


使幻灯片成为动画

最后一步是使用照片阵列,使幻灯片成为动画。您将需要两个项目:

  • 一个定时器
  • 在幻灯片中保持您当前位置的变量

将这两个项目添加到类定义,如 清单 6 所示。

清单 6. SlideshowViewController.h 已完成
#import <UIKit/UIKit.h>

@interface slideshowViewController : UIViewController<NSXMLParserDelegate> {
    IBOutlet UIImageView *imgView;
    NSMutableArray *photos;
    NSTimer *timer;
    int currentImage;
}

@end

timer 是将以您指定的时间间隔触发事件的对象。currentImage 只是进入照片阵列的索引,您可使用它遍历所有的图像。

清单 7 显示了幻灯片应用程序代码的最终版本。

清单 7. SlideshowViewController.m 已完成
#import "slideshowViewController.h"

@implementation slideshowViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    photos = [[NSMutableArray alloc] init];

    NSXMLParser *photoParser = [[[NSXMLParser alloc] 
      initWithContentsOfURL:[NSURL URLWithString:
      @"http://localhost/photos/index.xml"]] autorelease];
    [photoParser setDelegate:self];
    [photoParser parse];
    
    currentImage = 0;

    NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:0]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    [imgView setImage:[UIImage imageWithData:imageData]];

    timer = [NSTimer scheduledTimerWithTimeInterval: 5.0
                                             target: self
                                           selector: @selector(handleTimer:)
                                           userInfo: nil
                                            repeats: YES];
}

- (void) handleTimer: (NSTimer *) timer {
    currentImage++;
    if ( currentImage >= photos.count )
        currentImage = 0;

    NSURL *imageURL = [NSURL URLWithString:[photos objectAtIndex:currentImage]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    [imgView setImage:[UIImage imageWithData:imageData]];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
   attributes:(NSDictionary *)attributeDict { 
    if ( [elementName isEqualToString:@"photo"]) {
        [photos addObject:[attributeDict objectForKey:@"url"]];
    }
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:
     (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

清单 7 中的这两个新元素是用 viewDidLoad 方法创建定时器形成的,还添加了 handleTimer 方法,该方法在定时器被触发时会被调用。handleTimer 方法只递增 currentImage,如果到达阵列的末尾便会滚动索引。它还使用标准的图像抓取逻辑获得给定索引的图像,并显示该图像。

定时器有两种模式:它们可以一次性触发,也可以连续触发。在 viewDidLoad 方法中,示例会重复指定 YES,这样 handleTimer 方法会在应用程序的整个生命周期一次又一次地被调用。


结束语

在本文中,您创建了一个基本的 iOS 应用程序。现在可以在多个不同的方向使用该应用程序。iOS CoreGraphics 框架提供了一套丰富的转换,您可以使用这些转换激活图像之间的变化。您可以在后端使用 PHP 动态地生成 XML。或者,您甚至可以使用 CoreAudio API 把一些音乐放置在整个幻灯片的背景中。

参考资料

学习

  • Apple Developer Portal:获取 IDE,配置您的测试设备,并将完成的应用程序上传到应用程序商店。
  • iOS Developer Library:阅读该书架上关于开发 iOS 应用程序不可少的详细信息的入门文档,了解对 iOS 应用程序开发的基础知识。
  • W3C:精读各种标准。XML 标准 与本文关系密切。
  • Objective-C 语言:如果您需要复习 Objective-C 的独特语法,苹果公司可提供相关文档。
  • 重新构建 iPhone 聊天应用程序:(Jack D. Herrington,developerWorks,2011 年 1 月):从服务器代码一直到前端的用户界面,了解构建 iPhone 聊天应用程序的整个流程。
  • 本作者的更多文章(Jack Herrington,developerWorks,2005 年 3 月至今):阅读关于 Ajax、JSON、PHP、XML 和其他技术的文章。
  • XML 新手入门 获取您学习 XML 所需的参考资料。
  • developerWorks XML 技术专区:寻找提高您在 XML 领域技能所需的资源,包括 DTD、模式和 XSLT。参见 XML 技术库 获取广泛的技术文章和技巧、教程、标准和 IBM 红皮书。
  • IBM XML 认证:了解如何成为一名 IBM 认证的 XML 及相关技术的开发人员。
  • developerWorks 技术活动网络广播:随时关注这些活动中的技术。
  • Twitter 上的 developerWorks:立即加入以关注 developerWorks 推文。
  • developerWorks 播客:聆听针对软件开发人员的有趣的访谈和讨论。
  • developerWorks 演示中心:观看各种演示,从针对初学者的产品安装和设置,到针对经验丰富的开发人员的高级功能。

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


这是您第一次登陆到 developerWorks,已经自动为您创建了您的概要文件。 选择您概要文件中可以公开的信息的信息(如姓名、国家/地区,以及公司),这些信息同时也会与您所发布的内容相关联。 您可以随时更新您的 IBM 账号。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, Open source, Web development
ArticleID=783864
ArticleTitle=创建用于 iPad 的 iOS 幻灯片应用程序
publish-date=01042012