游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

写给中学生和新手的iOS应用制作教程(1)

发布时间:2013-06-01 09:50:25 Tags:,,,

作者:Mike Jaoudi

我曾在之前的教程中介绍了Objective-C的编程基础,你已经在之前教程中学习到很多东西,但你可能会有些疑惑“不是说教我如何制作iOS应用吗?可是到现在为止我做的只是命令行应用!”

好消息来了——漫长的等待结束了!现在你终于可以学习制作你的第一款iOS应用了!

在本教程中,你将制作一款简单的iOS游戏,它的玩法就是,玩家要在30秒内尽可能多地点击按键。不要兴奋得把屏幕按爆哦!

在本教程的第一部分,你将使用所有必需函数制作这个基本应用。在第二部分,你将在应用中添加自定义图像和声音,使它的外观更加精致!

开始

启动Xcode,然后选择File > New > Project。在左侧栏中,选择iOS下面的Application。接着双击Single View Application(单视图应用),如下图所示:

New-Project(from raywenderlich)

New-Project(from raywenderlich)

填写项目选项如下:

Product Name: Tap Me

Organization: 可以放空

Company Identifier: 格式可以是com.你的名字,如com.janesmith

Class Prefix: 可以放空

Devices:选择iPhone

确保只勾选Use Storyboard(使用故事板)和Use Automatic Reference Counting(使用自动引用计数)这两项。

Project-Setup(from raywenderlich)

Project-Setup(from raywenderlich)

现在选择保存项目文件的目录,然后点击Create。

运行

太好了!你现在已经完成Xcode设置了,可以开始开发你的iOS应用了。注意,运行应用时的一切配置都是正确的。保证选中屏幕左上角的iPhone Simulator(iPhone模拟器),然后点击Run,如下图所示:

Run-Project(from raywenderlich)

Run-Project(from raywenderlich)

Xcode项目启动时虽然功能是完全的,但起始项目什么也做不了,只展示模拟器的空白屏。你的应用看起来应该是下图所示的样子:

First-Simulator(from raywenderlich)

First-Simulator(from raywenderlich)

欣赏完你的杰作了没?返回Xcode,按下Stop按钮,停止应用。

看看项目的导航。这个项目与之前教程中的项目相比,差别很大。这个项目中,你可以看到在之前的Mac应用中没见过的很多新文件。

例如,main.m在哪里?别担心,它在Supporting Files(支持文件)文件夹中。但是等一下——有点奇怪。为什么main.m是在Supporting Files文件夹中,是否你的所有代码都必须进入那个文件?

打开main.m,看看里面的代码:

Main-File(from raywenderlich)

Main-File(from raywenderlich)

哼哼,在你放你的Mac应用的代码的地方,有一行奇怪的代码:

return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

这到底是什么,干什么用的?简单地说,这个UIApplication是作为你的应用的大脑。它使你的应用具有图像功能,使之可以利用iOS设备的所有功能。

虽然一般情况下,命令行应用在main.m中有更实用的代码,但典型的iOS应用只需要启动UIApplication和切换操作。

所以,你的应用运行的第一行代码仍然是main.m,但现在这个文件的目的只是创建一个新UIApplication。开发者遇到的99.99%的iOS应用是不需要编辑main.m;所以,可以把它放在Supporting Files文件夹中。

你是不是松了一口气?你可以放开main.m,继续制作应用的其他部分了。

加入Storyboard

如果不是在main.m中,你要从哪里开始制作应用呢?iOS的强大功能之一叫作故事板(Storyboard)。这是一种显示你设计的应用的发展流程的方法,不需要编写任何代码!听起来太容易了,对吧?

默认项目已经有一个Storyboard文件了,叫作MainStoryboard.storyboard。打开它吧!如下图所示:

Storyboard-File(from raywenderlich)

Storyboard-File(from raywenderlich)

这是基本故事板文件。到目前为止,它只显示空白屏,就像刚才看到的模拟器显示的一样:

Blank-Storyboard(from raywenderlich)

Blank-Storyboard(from raywenderlich)

你会注意到故事板视图两边各有一列工具条。在本教程的大多数时候,你需要显示这两列工作条,以方便作业!

切换到右边的Utilities侧边栏,即点击Xcode工具条的右上方的View(视图),如图所示:

Utilities-Button(from raywenderlich)

Utilities-Button(from raywenderlich)

切换到左边的Document Outline(文件大纲)侧边栏,即点击故事板的左下角的圆形箭头按钮。点击左指箭头会隐藏侧边栏;如果侧边栏被隐藏,箭头会显示成指向右边。

Document-Column(from raywenderlich)

Document-Column(from raywenderlich)

你最好把它工作视图调整成方便作业的样子!

内线着色

点击白色屏幕可以选择将背景改变成何种颜色。右边的Utilities侧边栏会显示当前选中的信息。你会对侧边栏的Attributes(属性)标签感兴趣吧,它位于左起第四项,看起来有点像滑块:

Attributes-Tab(from raywenderlich)

Attributes-Tab(from raywenderlich)

现在侧边栏显示了当前视图中所有可以改变的属性。找到标签为Background(背景)的下拉菜单:

Background-Color(from raywenderlich)

Background-Color(from raywenderlich)

点击白色小矩形,拉出颜色板,或点击“White Color”这行字,再选择“Other…”。选择清爽的绿色吧。

现在,点击Xcode工具条左上角的Run按钮,查看你的应用!

Color-Simulator(from raywenderlich)

Color-Simulator(from raywenderlich)

了不起!现在你的应用看起来更有意思了。但是,这么一面绿色屏是不会吸引玩家太久的。是时候添加用户界面元素了!

按钮

思考一相你的这款按钮点击游戏需要什么UI元素:

1、显示剩余时间的东西

2、玩家的当前得分

3、要点击的按钮

对于前两个元素,你可以使用显示文本的Label(标签)。

返回 Xcode的MainStoryboard.storyboard文件,在视图中添加两个Label。

在Utilities侧边栏的底部,有一个不同对象的库,你可以在里面找到一个名为Label的东西。

Label(from raywenderlich)

Label(from raywenderlich)

你要制作的第一个标签是计时器。一开始,它显示的是“Time: 30”,游戏开始后它就会30秒倒数。

从库中点击并拖动标签,放到视图的顶部。出现在视图中的蓝线可以帮你对齐物品,但你现在还不必关心这个。

现在,你的标签被选中,你可以看到Utilities侧边栏显示了它的可改变属性。找到Text属性并将其从“Label”变为“Time: 30”。另外,把对齐方式变成居中对齐,如下图所示:

hs-label-title(from raywenderlich)

hs-label-title(from raywenderlich)

文本似乎不太适合标签的默认大小。你必须重置标签的大小,使它更宽的。

你不必使标签与文本的宽度完全一致;相反地,你要多留一点宽度,保证有足够的空间用于倒数计时。

标签足够宽后,使它居于视图中间。当它接近于中间时,Xcode会显示一条断点蓝线,帮助你放置物品。

此时,你的故事板应该显示如下:

hs-storyboard(from raywenderlich)

hs-storyboard(from raywenderlich)

不错!现在,重复以上步骤,再放一个标签在接近视图底部的位置,用来显示当前得分;改变文本为“Score”,并且设置为居中对齐。

你希望得分在屏幕上显得醒目,那么就把这个标签的字体变得更大吧;做法是点击字体旁边的上箭头。因为你分两行显示玩家得分,所以要通过点击一次行数的上箭头将行数改成2。

hs-label-size(from raywenderlich)

hs-label-size(from raywenderlich)

像刚才一样,这个标签太小了,不适合显示两行文本!你必须重置它的大小,使它的宽度容纳得下“Score”,高度容纳得下两行文本。此时,你的故事板应该显示如下:

hs-storyboard-2(from raywenderlich)

hs-storyboard-2(from raywenderlich)

现在,你需要的最后一个UI元素是什么?是的,让用户点击的按钮!

从对象库中找到一个叫作Round Rect Button(圆角矩形按钮)的东西,如下图所示:

Button-Location(from raywenderlich)

Button-Location(from raywenderlich)

从库中点击并拖动Round Rect Button到你的视图中,放在两个标签之间。确保选中这个按钮,然后到侧边栏中查看它的属性。

按钮通常显示玩家应该采取的活动,所以把无聊的“Button”改成“Tap Me!(点我!)”吧。因为你的按钮就是你的应用的主要事件,所以你要把它的尺寸和字体都设置得更大。

你的故事板现在是这样的:

hs-storyboard-3(from raywenderlich)

hs-storyboard-3(from raywenderlich)

简单的按钮点击游戏的布局已经做好了!看起来有些像真正的应用了,对吧?到现在,你还没写过任何代码,真是太轻松了!

然而,在屏幕之后,Xcode正在做许多工作。下面内容解释了View(视图)和View Controller(视图控制器)在你的应用中的神奇作用!

View和View Controller

看看故事板左边的Document Outline侧边栏,顶层视图(游戏邦注:带有简单的名称“View”)是背景层,是你之前设置背景颜色的地方。它里面是两个标签和一个你刚才添加的“Tap Me!”按钮。

在iOS应用中,你在屏幕上可以看到的任何东西都是一种View。那意味着你的标签和按钮也是一种视图。

hs-view-outline(from raywenderlich)

hs-view-outline(from raywenderlich)

如果你想与视图互动——如通过代码或点击改变它的属性,你需要一个叫作Controller(控制器)的东西。看左栏,你会看到这个视图、标签和按钮都在一个叫作View Controller的东西中。

这个View Controller的作用就是,管理所有放在它里面的视图。View Controller负责对付应用屏幕背后的工作,管理所有发生在视图中的活动。例如,当按钮被点击时,View Controller会响应接下来发生什么事。

是时候深入了解View Controller的作用了!

控制View Controller

Xcode帮你写了一些基本的起始代码,你可以打开文件ViewController.h查看View Controller的代码:

View-Controller-Header(from raywenderlich)

View-Controller-Header(from raywenderlich)

记住,页眉文件是用于声明程序的不同部分的。声明只是表示它存在,但没有显示实际执行的细节。

在接近页眉文件的顶部的地方有这么一行代码:

@interface ViewController : UIViewController

改变这行代码如下:

@interface ViewController : UIViewController {
IBOutlet UILabel *scoreLabel;
IBOutlet UILabel *timerLabel;
}

以上代码会设置名为scoreLabel和timerLabel的实例变量,之后你可以用来在程序中改变标签文本。IBOutlet是向Xcode提示你希望以它作为出口,UILabel是文本标签的类名称。

接下来,添加方法调用buttonPressed的声明。这一行代码必须放在标明@end的代码前面:

- (IBAction)buttonPressed;

IBAction向Xcode提示,这个方法与某些活动有关,如按键点击或切换。你填写完执行后,可以把“Tap Me!”按钮与buttonPressed方法关联起来。

转到ViewController.m,看看执行代码。

View-Controller-Implementation(from raywenderlich)

View-Controller-Implementation(from raywenderlich)

Xcode提供数种方法。一种叫作viewDidLoad,当视图加载时,这个方法就会被调用,准备显示。当设备运行内存不足时,didRecieveMemoryWarning就会被调用;当然,在这个教程应用中,你不必担心这个问题。

可以添加buttonPressed方法了。在文件末尾添加以下代码:

- (IBAction)buttonPressed {
NSLog(@”Pressed!”);
}

完美!当这个方法被调用时,NSLog方法显示一切是否按你期望的样子在你的应用中运行。

关联

你已经设置好应用的故事板和view controller代码。现在可以把活动与输出关联起来了。

打开MainStoryboard.storyboard。把光标放在“Tap Me”按钮上,按下Control键,然后点击并拖动到绿色背景上的任意位置。你会看到一条蓝线与你拖动光标的地方相连:

hs-action11(from raywenderlich)

hs-action11(from raywenderlich)

当你松开鼠标或触控板,会弹出一个小窗口。太好了,这就是buttonPressed方法的效果!现在选择它:

hs-action2(from raywenderlich)

hs-action2(from raywenderlich)

因为你用IBAction关键词声明buttonPressed,所以Xcode会把它作为一个选项。如果你在窗口中没有看到buttonPressed,那就返回一步,查看ViewController.h头文件中的代码。

可以测试这个按钮了!运行应用,点击按钮几次。你的buttonPressed方法应该被调用,你会看到如下调试输出结果:

hs-console(from raywenderlich)

hs-console(from raywenderlich)

很好,这个按钮可以用!你的应用已经接近完工了!

注意,为了关联活动,你要按下控制键的活动,然后点击并拖动按钮(视图)到view controller(在背景区域)。

然而,为了将输出与Label关联起来,你必须做相反的事:按下控制键,然后从view controller(游戏邦注:表现为底部的黄色圆形按钮)点击并拖动到“Score”上,如下图所示:

hs-label1(from raywenderlich)

hs-label1(from raywenderlich)

这就是你之前在代码中制作的scoreLabel!选中它:

hs-label2(from raywenderlich)

hs-label2(from raywenderlich)

现在,这个标签已经关联好了,可以从代码中打开了!同样的做法,把输出口与timerLabel关联起来。这一次,你必须从view controller中点击并拖动到“Time: 30”上。

好了,你的应用已经关联好活动,也设置好调试代码了。接下来要做的是,当玩家点击按钮时触发倒数计时事件和计分时件。

标签

你已经确定按钮是可以使用的,所以现在是时候对标签文本做同样的事了。在ViewController.m中,再次输入你之前写给buttonPressed方法的代码:

- (IBAction)buttonPressed {
scoreLabel.text = @”Pressed!”;
}

scoreLabel变量是与故事板上的UILabel关联的输出口。现在,当按钮被按下时,这个标签文本就会变化。

运行应用,看看buttonPressed是否被调用,以及标签是否正确地变化!

你正在从代码中设置标签文本,但你还可以通过程序改变许多更有趣的属性如文本颜色、大小、排列方式等。iOS Developer是一个学习UILabels和UIButtons的功能的好资料。

测试

既然界面做好了,代码也能运行了,那就可以停下考虑游戏的机制了。

你要记录的东西如下:

1、点击按钮的次数

2、剩余时间的秒数

3、记录时间的方法

可以添加更多变量了!在ViewController.h后面添加如下代码:

@interface ViewController : UIViewController {
IBOutlet UILabel *label;
IBOutlet UILabel *timerLabel;

// Add the next three lines
NSInteger count;
NSInteger seconds;
NSTimer *timer;
}

在以上代码中,“count”变量会记录按钮点击的次数,“seconds”变量会记录剩余时间的秒数。NSInteger(整数)型更合适,因为它可以储存从0到200万的整数。可以肯定没人能在30秒内点击按钮达到那么多次!至于“timer”变量,放在下面部分来说。

当玩家点击按钮时,你必须增加点击计数,用新数字更新标签。改变buttonPressed方法如下:

- (IBAction)buttonPressed {
count++;

scoreLabel.text = [NSString stringWithFormat:@"Score\n%i", count];
}

以上代码可能看起来有点儿乱,所以把它分解如下:

“Score”——就是简单的单词“Score”

“\n”——换行符。在它之后的所有文本都会跳到下一行。

“%i”——整数的占位符。在这个应用中,“%i”将会被替换成变量count。

再次运行应用!点击按钮若干次,你会看到随着点击数增加,得分也在增加!

hs-run-2(from raywenderlich)

hs-run-2(from raywenderlich)

好吧,你不能让你的玩家无限点击按钮,对吧?所以你需要一个倒数计时器。

计时器

现在游戏可以运行,且能够计分,接下来你要做的就是,设置一个从30秒开始倒数到0的计时器。

首先,设置一个能初始化游戏状态的方法。添加这个方法到ViewController.m:

- (void)setupGame {
// 1
seconds = 30;
count = 0;

// 2
timerLabel.text = [NSString stringWithFormat:@"Time: %i", seconds];
scoreLabel.text = [NSString stringWithFormat:@"Score\n%i", count];

// 3
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(subtractTime)
userInfo:nil
repeats:YES];
}

这个方法的第一部分会将时钟重置为30秒,将计数重置为0。这就是游戏的初始状态。

这个方法的第二部分会重置屏幕显示。你对stringWithFormat调用和%i应该已经熟悉了。

第三部分是设置每秒向游戏发送信息的NSTimer对象。这样,游戏就能够更新剩下的秒数,并在30秒后结束游戏。

如果你将NSTimer调用的各个部分分解出来,可能会有些吓人:

Time Interval是时间间隔,表示计时器多长时间更新一次(在我们的应用中,这个时间间隔是1秒)

Target(目标)是每秒发送信息的接收对象。你现在就在view controller中,你希望信息送往view controller,所以这个Target就是self。

Selector(选择器)是你想调用的方法。你必须在这个方法的名称前面添加@selector。

User Info(用户信息)是你想储存在计时器中的所有额外信息。在本应用中,你不需要它,所以应该设置为nil表示无。

Repeats(重复)表示计时器是否需要重复。你希望计时器每一秒都运行,直到你叫停,所以应该设置为YES。

你要求计时器每秒都调用一次subtractTime方法,但你还没有定义它呢!

在ViewController.m中添加如下代码:

- (void)subtractTime {
// 1
seconds–;
timerLabel.text = [NSString stringWithFormat:@"Time: %i",seconds];

// 2
if (seconds == 0) {
[timer invalidate];
}
}

这个方法的第一部分看起来很眼熟吧。在这里,你减少秒数,并用新时间更屏幕上的标签。

当秒数为0时,计时器将停止,游戏也结束。当你设置计时器为无效时,它会通过再次调用subtractTime停止计时器。

最后再做一些小事,你的应用就大功告成了!

开始和停止

现在我们已经完成很多工作了!为了让东西保持简单,当应用启动时,你就可以开始游戏,同时开始计时。更新ViewController.m中的viewDidLoad方法如下:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupGame];
}

记住,当故事板和视图加载完毕后,iOS会自动调用viewDidLoad。接下来,游戏就会调用你刚写好的setupGame方法。

启动应用,看看你能得多少分!

hs-run-3(from raywenderlich)

hs-run-3(from raywenderlich)

游戏结束

你有没有注意到一些奇怪的事,也就是,你的应用怎么结束游戏?

当计时器显示为0时,你仍然可以点击“Tap Me”按钮,所以你必须想办法阻止玩家继续点击下去。另外,游戏无法重启和重玩。好吧,都很成问题!

提示似乎挺合适的。当游戏结束时,你可以添加一个弹出提示窗口,显示玩家得分和重玩按钮。因为你希望提示在游戏结束时出现,所以它的代码应该添加在subtractTime方法中:

// 2
if (seconds == 0) {
[timer invalidate];

// new code is here!
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Time is up!”
message:[NSString stringWithFormat:@"You scored %i points", count]
delegate:self
cancelButtonTitle:@”Play Again”
otherButtonTitles:nil];

[alert show];
}

UIAlertView需要名称、信息和一个或以上的按钮。这段新代码的第一部分是设置提示,然后发送结果信息给用户。

把提示调用的各个部分分解如下:

Title(名称)——出现在提示的顶部。

Message(信息)——在提示的中间。在这个提示中,要显示得分。

Delegate——设置为self,与计时器一样。这个Delegates留到后面再解释。

Cancel Button Title(取消的按钮名称)——这个按钮的名称。对于这款应用,应该是“Play Again”。

Other Button Titles——其他一系列按钮的名称。你只需要一个Play Again按钮,所以设置为nil。

现在,启动应用,看看你的应用最终版如何!

hs-run-4(from raywenderlich)

hs-run-4(from raywenderlich)

太棒了!所以现在弹出的提示能显示得分。按下“Play Again”按钮……咦?怎么没有反应?

在你的故事板中,你把IBAction与处理点击事件的按钮相关联,但没有为提示按钮设置关联。这时候,你就要用到上面提到的delegate。

delegate

delegate的作用是让对象发现正在发生的事件。例如,你可能把你的闹钟调到早上7点闹铃,或者,你可能叫你的朋友到家时给你打个电话。在这些例子中,你就是delegate(被告之的对象),而闹钟和你的朋友则是告诉你事件(游戏邦注:如“该起床了”或“我到家了”)的对象。

回到应用,当“Play Again”被点击时,你的提示要告诉用户某事件。当事件发生时,你的view controller应该知道它发生了,所以view controller就是提示的delegate。

所以,你必须声明View Controller为delegate。在ViewController.h顶部,改变带“@interface”开头的代码如下:

@interface ViewController : UIViewController<UIAlertViewDelegate> {

就像闹钟有可以发送的信号(播放音乐或铃声),UIAlertView也有一套信息可以发送给它的delegate。你可以查看完整列表的文件,你需要的是一个叫作“alertView:clickedButtonAtIndex:”的东西。当玩家点击按钮时,它将发送信息。

现在,你只要把这个方法放进View Controller!

添加如下代码到ViewController.m中:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
[self setupGame];
}

简而言之:当游戏结束时,UIAlertView会显示得分和按钮。当玩家点击按钮时,信息会发送给delegate——view controller,然后它将调用setupGame方法。setupGame将重置时间和得分,并使游戏重新开始。

你还等什么?再次运行你的应用!

恭喜你!现在你已经做好你的第一款iOS应用了——记得让你的家人和朋友瞧瞧!

结尾

以上就是利用你目前为止学习到的代码做出的项目。

通过制作这个简单的小应用,你可以更加了解UI元素、View和View Controller的功能。请尝试一摆弄一下这个应用的其他部分,看看你能否改变应用的外观或添加其他功能!

在这篇教程的后半部分,你将学习到如何给应用添加美术设计和声音,使它更加精致,以丰富玩家的体验。(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦

iOS for High School Students: Making Your First iOS App: Part 1/2

by Mike Jaoudi

Welcome back to our iOS for High School Students tutorial series!

In the first two tutorials in the series, you learned the basics of programming in Objective-C. Specifically:

In the first tutorial, you learned how to make a “Are you a WIZARD?” game. In the process, you learned about variables, logging, if statements, and while loops.

In the second tutorial, you learned how to make a command-line text adventure game. In the process, you learned about arrays, classes, objects, methods, and properties.

You learned a lot in those tutorials, but you might have thought to yourself – “Wait a minute, I thought this was supposed to be about making iOS apps, but all I’ve made so far is command lineapps!”

Well, good news – the long wait is over! You are now ready to make your first iOS app at long last!

In this tutorial, you will create a simple iOS game where you have to tap a button as many times as you can in 30 seconds. Just don’t get too excited and smash your screen by mistake! :]

In this first part, you’ll create the basic app with all of the required functionality in place. In the second part of the tutorial, you will add custom images and sounds to your app to give it a more polished appearance!

Sound good? Then time to dive right in and get started!

Getting Started

Start up Xcode, and select File > New > Project. In the left sidebar, select Application under iOS. Then double click Single View Application, as below:

Fill in the project options as follows:

Product Name: Tap Me

Organization: can be left blank.

Company Identifier: use something like com.yourname, such as com.janesmith

Class Prefix: can be left blank.

Devices: select iPhone.

Make sure that Use Storyboard and Use Automatic Reference Counting are the only two items checked.

Now choose the directory to where you want to save the project files, and click Create.

Off and Running!

Great! You now have everything setup in Xcode to start developing your iOS app; now is a great time to make sure that everything is configured correctly by running the app. Make sure that iPhone Simulator is selected in the upper left corner of the screen and then press Run, as below:

Xcode projects start off as fully-functional apps, but the starter project will do nothing but display a blank white screen in the simulator. Your stunning app should look like this:

Have you finished admiring your awesome app yet? :] Return to Xcode and press the Stop button to stop the app.

Take a look at the project navigator. This project looks quite a bit different than the project in the previous tutorials. There are a lot of new files inside this project that you didn’t see with your previous Mac application.

For example, where is main.m? No worries; it’s in the Supporting Files folder. But wait a minute — that’s a little odd. Why is main.m in the Supporting Files folder, if all of your code needs to go inside that file?

Open up main.m and have a look at the code inside:

Hmm — in the section where you placed your code in the Mac application, there is a strange line of code:

return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

What on earth is this and what does it do? In simple terms, the UIApplication serves as the central brain of your app. It gives you a powerful app with graphical capabilities that allows your app to take advantage of all of the features of an iOS device.

While command-line applications will normally have more useful code in main.m, the typical iOS app just needs to boot up UIApplication and hand off control.

So the first code that runs in your application is still main.m, but now the sole purpose of this file is just to create a new UIApplication. In 99.99% of the iOS apps you’ll encounter as a developer, you never need to edit main.m; therefore it is stored away in the Supporting Files folder.

Did you just breathe a sigh of relief? :] You’ll leave main.m for now and head on into building the rest of your app!

Two Sides to Every Story — Introducing Storyboards

Where do you start building the app if not in main.m? One great feature in iOS is called Storyboards. Storyboards are a method of designing the visual appearance and flow of your app, without having to write any code! This is sounding easier and easier, isn’t it ? :]

The default project already has a Storyboard file in it called MainStoryboard.storyboard. Go ahead and open it up! You’ll see the following:

This is the basic storyboard file. So far, it is just displaying a blank white screen, just like the simulator showed when you ran the app earlier:

You’ll notice there are sidebars on both sides of the storyboard view. Most of the time in this tutorial, you’ll want to have both sidebars visible to make your life a little easier! :]

To toggle the Utilities sidebar on the right, click the button in the top-right of the Xcode toolbar in the View section, as below:

To toggle the Document Outline sidebar on the left, click the round arrow button in the lower-left corner of the storyboard. The left-pointing arrow will hide the sidebar; if it’s hidden, it will turn into a right-pointing arrow to show the sidebar.

As exciting as the white background is, you’ll probably want to change it to something a little snappier!

Coloring Inside the Lines

To change the background color, click anywhere inside the white view to select it. The Utilities sidebar on the right will show the details of whatever is currently selected. You’re interested in

the Attributes tab in the sidebar; it’s the fourth one from the left and looks like a little slider:

The sidebar now shows all of the attributes that can be changed for the view. Find the drop down menu labeled Background:

Click the small white rectangle to bring up the color palette, or click the words “White Color” and select “Other…” Choose a nice green color for your app.

Now click the Run button in the upper left corner of the Xcode toolbar to check out your app!

Amazing! Now your app is starting to look a little more interesting. However, you won’t entertain your user for long by staring at a green screen. Time to add some user interface elements!

Tap Me!

Think for a minute about the user interface elements you will need for your button-tapping game:

Something to indicate how much time is left

The player’s current score

A button to tap

For the first two elements, you’ll use Labels which display text.

Return to the MainStoryboard.storyboard file in Xcode to add these two Labels to the view.

At the bottom of the Utilities sidebar, there is a Library of different objects. Scroll down until you find one called Label.

The first label you’ll create will be your timer. It will start by saying “Time: 30″ and then count down when the game starts.

Click and drag a label from the library and place it near the top of the view. The blue lines that show up on the view are guides to help you line up objects, but you don’t have to worry about that yet.

Now that your label is in the view and is selected, you’ll notice the Utilities sidebar now shows the attributes you can change for a label. Find the Text attribute and change it from “Label” to

“Time: 30“. Also, change the alignment to be center-aligned, as seen in the screenshot below:

Whoops — it looks like the text doesn’t quite fit inside the default size of the Label. You’ll need to resize the label to make it wider.

You don’t have to make the Label exactly the width of your text; instead, give it a little extra width just to be sure that you’ll always have enough room for your countdown.

Once the label is wide enough, move it so it’s centered in the view. When it’s close to being in the center, Xcode will show a dotted blue line as a guide to help you position your objects.

At this point, your storyboard should look something like this:

So far so good! Now, repeat the steps above to place one more label near the bottom of the view to show the current score; change the text to say “Score”, and make it center-aligned.

You want the score to stand out on the screen, so make the font size of this Label bigger by clicking the small up-arrow next to the font size. Since you’ll display the player’s score on two lines, change the number of lines to 2 by clicking the small up-arrow for Lines.

As before, the label is way too small to fit the two lines of large text you’ll need! Resize the label so it’s wide enough to fit the word “Score”, and tall enough to fit two lines of text. At this point, your storyboard should look something like this:

Now what was that last user interface element that you needed? Oh yeah — a button for the user to click! :]

Scroll through the object library and find a Round Rect Button, as below:

Click and drag a Round Rect button from the library onto your view in between the two labels. Make sure the button is selected in your view, and have a look at its attributes in the sidebar.

Buttons should usually indicate the action the user should take, so change the title from boring Button to a more exciting Tap Me!. Since your Button is really the main event of your app, resize the button to make it bigger, and while you’re at it, make the font size larger too!

Here’s a final look at what your storyboard should look like:

The basic layout of your simple button-tap game is now in place! It’s starting to look like a real app, isn’t it? :] Up until now, you haven’t really written any code, which is pretty cool!

However, as you’ve correctly surmised, Xcode is doing a lot of work behind the scenes. Take a minute and have a look through the next section which explains the magic of the Views and View

Controllers at use in your app!

Behind the Curtain — Views and View Controllers

Look at the Document Outline sidebar to the left of the storyboard. The top-level view (with the simple name “View”) is the background layer and is where you set the background color earlier.

Inside of it are the two labels and the “Tap Me” button that you added to the app.

In an iOS app, just about anything that you can see on the screen is a kind of View. That means your label and button are also types of views.

If you want to interact with views – such as change their attributes from code or check if the user tapped on them – you use something called a Controller. Look back at the left column, and you’ll see that the the view, label and button are all inside something called View Controller.

The job of this View controller is to manage all of the views that are stored inside it. View controllers handle the behind-the-scenes jobs of your app, and are in charge of all of the actions that happen inside the views. For example, when the button is tapped, the view controller will take care of what to do.

Time to dive just a little deeper and check out what this View Controller does!

Controlling the View Controller

Xcode wrote some basic starter code for you, so start by opening the file ViewController.h to have a look at the code for the view controller:

Remember that a header file is used to declare different parts of the program. Declaring means to say that it exists, but doesn’t give the actual implementation details.

You need some way to refer to the two labels you added earlier. This is called an outlet in Xcode, where some variable in the view controller refers to some user interface element in the storyboard view.

Near the top of the header file will be a line like this:

@interface ViewController : UIViewController

Change that line and add a few additional lines so it looks like this:

@interface ViewController : UIViewController {
IBOutlet UILabel *scoreLabel;
IBOutlet UILabel *timerLabel;
}

The code above will set up instance variables called scoreLabel and timerLabel that you can use later on to programatically change the label text. IBOutlet is a hint to Xcode that you want it to be

an outlet and UILabel is the class name for a text label.

Next, add the declaration for a method called buttonPressed. This line should go just above the line that says @end:

- (IBAction)buttonPressed;

IBAction is another hint telling Xcode that this method will be connected to some action, such as a button press or a switch being toggled. After you fill in the implementation, you can connect the“Tap Me!” button to call the buttonPressed method.

Switch over to ViewController.m and have a look at the implementation code.

Xcode has stubbed out a few methods. One is called viewDidLoad, which gets called after the view has loaded and is ready to be displayed. The didRecieveMemoryWarning method gets called when the device is running low on memory; there’s no need to worry about this method in your tutorial app!

It’s time to add the implementation for the buttonPressed method. Add the following code toward the end of the file, before the line that says @end:

- (IBAction)buttonPressed {
NSLog(@”Pressed!”);
}

Perfect! The NSLog method will write out to the console when the method is called so you’ll be able to tell that everything is working as expected when you run your app.

Connecting the Dots

You’ve set up the look of the app in the storyboard and set up the view controller code. Now it’s time to connect the action and outlets to get the storyboard and code talking to each other! :]

Open up MainStoryboard.storyboard. With the cursor over the “Tap Me” button, hold down the Control key, then click and drag to anywhere in the green background. You will see a blue line connecting the button to wherever you drag your cursor:

When you release the mouse or trackpad button, a little window will pop up. Hey, cool — there’s the buttonPressed method that was created earlier! Select it now to hook the two together:

Because you declared buttonPressed with the IBAction keyword, Xcode offers it as a choice here. If you don’t see buttonPressed in the window, go back one step and check your code in the

ViewController.h header file.

Time to test out the button! :] Run the app and tap the button a few times. Your buttonPressed method should be getting called and you will see some debugging output, as below:

Great, a working button! You’re closing in on your completed app!

Note that to connect an action you held down the control key, then clicked and dragged from the button (the view) to the view controller (in the background area).

However, to connect an outlet to the label, you need to do the opposite: hold down the control key, then click and drag from the view controller (represented by the round yellow icon at the bottom) to the “Score” label , just like below:

Yup, there’s scoreLabel, which you created in your code earlier! Select it now:

Now the label is connected and accessible from the code! Do the same thing to connect the outlet to timerLabel. You need to control-click and drag from the view controller to the “Time: 30″ label this time.

Okay, you have things connected and some console debugging code setup in the app. But you still need the countdown to happen, and the score to change when the player taps the button. Head on in to the next section to do this now!

Labeling Labels

You’ve already made sure the button works, so it’s time to do the same with changing the label’s text. In ViewController.m, replace what you previously wrote for the buttonPressed method with this code:

- (IBAction)buttonPressed {
scoreLabel.text = @”Pressed!”;
}

The scoreLabel variable is the outlet connected to the UILabel in the storyboard. Now when the button is pressed, the label text should update.

Build and Run the app to see for yourself that the buttonPressed gets called and properly updates the label! Neat, eh?

You’re setting the label text from code, but there are many more interesting attributes such as text color, size, alignment, and others that you can access programatically. The iOS Developer documentation is a great way to learn more about all the things your UILabels and UIButtons can do.

Testing, Testing, 1, 2, 3

Now that the interface is set up and the code is running, pause for a moment and think about the game mechanics.

There are a few things you’ll need to keep track of:

The number of times the button was pressed

The number of seconds remaining

Some way to keep track of time

Time to add a few more variables! Add the code below to ViewController.h:

@interface ViewController : UIViewController {
IBOutlet UILabel *label;
IBOutlet UILabel *timerLabel;

// Add the next three lines
NSInteger count;
NSInteger seconds;
NSTimer *timer;
}

In the code above, the “count” variable will hold the number of button taps, and “seconds” will hold the number of seconds remaining. The NSInteger type makes the most sense since it can store integers (whole numbers) from zero up to over two billion. Here’s hoping that no one who tries your app can tap that many times in 30 seconds! :] The “timer” variable will be dealt with in the next section.

When the player taps on the button, you need to increase the tap count and update the label on screen with the new count. Change the buttonPressed method as below:

- (IBAction)buttonPressed {
count++;

scoreLabel.text = [NSString stringWithFormat:@"Score\n%i", count];
}

The code above probably looks a little obtuse, so break it down piece by piece:

“Score” – The plain old word “Score”

“\n” – A line break. Everything else after this will be on the next line

“%i” – A placeholder for an integer. In this case, the “%i” will be replaced by your variable count

Build and run the app! Tap the button a few times, and you should see your score increase as you tap!

Well, you can’t give your player unlimited time to tap the button, can you? :] Looks like you need a countdown timer!

Time For a Timer

Now that game works and keeps score, you’ll need to set up the timer to count down from 30 seconds to zero, when the player’s turn will end.

First, set up a method that will initialize the game state. Add this method to ViewController.m:

- (void)setupGame {
// 1
seconds = 30;
count = 0;

// 2
timerLabel.text = [NSString stringWithFormat:@"Time: %i", seconds];
scoreLabel.text = [NSString stringWithFormat:@"Score\n%i", count];

// 3
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(subtractTime)
userInfo:nil
repeats:YES];
}

Part 1 of the method resets the clock to 30 seconds and the tap count to 0. This will be the initial state for the game.

Part 2 of the method resets the on screen display. The stringWithFormat call and the %i should already be familiar to you!

Part 3 is one dense-looking bit of code. Here, you’re setting up a NSTimer object that will send you a message every second. That way, you’ll be able to update the number of seconds remaining and end the game after 30 seconds.

If you break down the various parts of the NSTimer call, it isn’t too scary:

Time Interval is simply how often you want the timer to go off (1 second, in this case)

Target is which instance to send a message to every second. You’re in the view controller now and you want the message to go to the view controller, so the target is self.

Selector is what method you want to call. It isn’t enough to write the method, you also need to put @selector around the method name.

User Info is any extra info you want stored with the timer. You won’t need anything for this timer so you say nil to represent nothing.

Repeats says if the timer should repeat or just fire off once. You want the timer to go off every second until you say stop, so this is set to YES.

You’ve asked the timer to call the subtractTime method every second but you haven’t defined it yet! :]

Add the following code to ViewController.m:

- (void)subtractTime {
// 1
seconds–;
timerLabel.text = [NSString stringWithFormat:@"Time: %i",seconds];

// 2
if (seconds == 0) {
[timer invalidate];
}
}

Part 1 of the method should be familiar looking. Here, you’re decreasing the number of seconds and then updating the label on screen with the new time.

When the number of seconds hits 0, you’ll want the timer to stop and end the game. When you tell the timer to invalidate, it will stop the timer from calling subtractTime again.

There’s just a few last-minute things to add to your app until it’s done!

Starts and Stops

Lots of pieces are now in place! To keep things simple, you can just start the game, and the timer, when the app launches. Update the viewDidLoad method in ViewController.m:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupGame];
}

Remember, iOS will call viewDidLoad automatically for you when the storyboard and view are loaded. The call to the setupGame method you just wrote will then start things off.

Launch the app and see what kind of high score you can reach!

Game Over Weirdness

Did you notice a few odd things about how your app handles the end-of-game scenario?

When the timer hits zero, you can still tap the “Tap Me” button, so you’ll need some way to prevent the user from clicking it! As well, there’s no way to restart the game and try again.

Hmm,that could be a problem!

An alert sounds like a good fit here. When the game is over, you can add an alert that will pop up showing the score and displaying a button to the user that that lets you play the game again.

Since you want the alert to show when the game is over, add the code for it inside the subtractTime method:

// 2
if (seconds == 0) {
[timer invalidate];

// new code is here!
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Time is up!”
message:[NSString stringWithFormat:@"You scored %i points", count]
delegate:self
cancelButtonTitle:@”Play Again”
otherButtonTitles:nil];

[alert show];
}

A UIAlertView has a title, message, and one or more buttons. The first part of the new code sets up the alert, and then sending it the show message will display it to the user.

Break down the various pieces of the alert call, and you’ll see the following:

Title – the title that will appear at the top of the alert.

Message – the message in the center of the alert. In this alert, you want to display the score.

Delegate will be set to self, just like the timer. Delegates will be explained in the next section.

Cancel Button Title – the title of the button. For this app, it is Play Again.

Other Button Titles – a list of button titles. You only need a play again button so set this to nil.

Now, build and run the project and see how your new, end-game code works!

Awesome! So the alert now pops up and shows the high score. And pressing “play again”…uh, doesn’t do anything! What gives?

In your Storyboards, you connected an IBAction to the button to handle the tap events, but there’s nothing like that for alert buttons. Instead, you need to use something called a delegate.

Dealing With Delegates

A delegate is a way for an object to find out about interesting things that are happening. For example, you might set your alarm clock to wake you up at 7 in the morning or you might ask your friend to call you when she gets home. In these examples, you are the delegate (the thing being told) and the alarm clock and your friend are the things that will tell you something (such as, “it is time to wake up” or “I am now at home”).

Going back to the app, your alert has something interesting to tell – when the “Play Again” button is pressed. Your view controller would love to know when that happens, so it should become the alert’s delegate.

So you need to state that the View Controller is a delegate for UIAlertView. Near the top of ViewController.h, change the line starting with “@interface” like this:

@interface ViewController : UIViewController<UIAlertViewDelegate> {

Just as the alarm clock has a certain signal it can send (playing music or an alarm sound), UIAlertView has a set of messages it can send to its delegate. You can check out the documentation for a full list, but the one you’re concerned with here is called “alertView:clickedButtonAtIndex:”. This will send a message when a button is clicked.

Now you just have to put that method into the View Controller!

Add the code below to ViewController.m:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
[self setupGame];
}

To summarize: when the game ends, a UIAlertView will be displayed with the score and a button. When the button is tapped, a message will be sent to the delegate — your view controller — which will then call the setupGame method you wrote a while back. To refresh your memory, setupGame resets the time and score and restarts the game.

What are you waiting for? Build and run your app and test your skills in a button tapping frenzy!

Congratulations!! You have now made your first iOS app – be sure to show it off to your family and friends!

Where To Go From Here?

Here is an example project with all of the code you’ve developed in this tutorial so far.

This is a great little app to play around with to get a feel for how UI elements, Views and View Controllers work. Feel free to play around with different parts of the app. See if you can change the look of the app or try adding additional features!

In part 2 of this tutorial, you will learn how to add artwork and sounds to the app to make it more polished and to give the user a better playing experience.(source:raywenderlich)


上一篇:

下一篇: