导语:目前学完了The iOS Apprentice的第一个系列,在此总结一下。我采用的是第2版本(Objective-C语言版本)
这是The iOS Apprentice系列的第一个项目,手把手的教你如何开发一个滑动靶心猜数值的简单小游戏。游戏完成的界面如下:
此教程对于初学者非常友好,没有相关基础知识也能照着学下来,不过我觉得还是先学一下Objective-C语言的基本语法会更有效率些。
本书采用的学习方式是:先告诉你做什么,怎么做,然后再结合理论知识讲解为什么这么做。
开发APP第一步:做什么(What)
The to-do list待办事项清单
开发一个App的第一步是明确需要做什么,而不是如何去实现。根据功能需求列出需要做的事项清单。比如本教程中的例子,需要开发一个通过滑动滑条,使其数值越接近给定的目标值,所得的分数就越高的小游戏。
怎么列这个待办事项呢?我目前是这样做的:
- 根据需求描述,画出游戏界面,列出需要使用的对象,比如本例中,滑条,按钮,标签等。
- 对应的每个对象,都需要实现什么样的功能,比如本例中,滑动滑条能显示出数值,点击按钮显示弹出窗口告诉玩家分数等。
- 按照玩法的流程,实现相应的动作和数值变化,这部分要理清各部分的逻辑关系。
- 最后完善游戏界面,改善游戏体验。
开发APP第二步:怎么做(How)
在完成了做什么之后,就根据列出来的待办事项清单逐个来实现。
- 首先要在主界面视图里,添加视图对象,什么按钮啊,标签啊,滑条等。在iOS里每个界面都有自己独立的视图控制器,在本例中目前还只有一个界面,所以只需要一个视图控制器。
One of the design principles of iOS is that each screen in your app gets its own view controller.
- 然后在.h声明文件里先声明对象,在.m实现文件里实现这个对象所需的实例变量和方法或动作。.h声明文件告诉计算机是什么,视图控制器里有什么,是什么样的。.m实现文件则告诉计算机怎么做,视图控制器里的对象是怎么运行的。
the .h file tells the computer what the view controller does, while the .m file tells the computer how it does those things.
那么APP是如何运作的呢?
本教程中有这样一个图:
一个APP是有一些对象组成,这些对象通过相互发送消息来实现某些功能。在iOS里,APP是由事件驱动(event-driven)的应用,也就是说对象们等待一些明确的事件发生来触发它们发送消息,执行相应的方法。比如按钮这个对象,只有你点击它,它才会执行它的方法。其实一个APP大部分时间都是在等待,等待触发它的事件发生,当它执行完后,继续等待。
说了这么多对象,那对象到底是什么呢?
有句话说:万物皆对象。我们人类所接触的具体存在的事物是对象,比如人,电脑等,所抽象出来的描述也是对象,比如指令,数据等。每个对象都包含数据和方法:
- 数据包含些什么东西(Data contains something)
- 方法做些什么东西(Functionality(methods) does something)
在上图中,你(you)是一个对象,你现在有个办派对的能力(方法),你需要打扫房间,准备好音乐,还需要冰淇凌,但是你附近没有卖冰淇凌的,不过你好朋友史蒂夫(Steve)他家附近有卖的,史蒂夫是一个对象,他有买冰淇凌的能力(方法),打开钱包,来到商店,付钱购买冰淇凌,然后来参加你的派对时就带给你冰淇凌。图中清楚的显示了,对象都包含哪些方法和数据。
对象里的数据可以是常量,也可以是变量,常量顾名思义它的值是固定不变的,而变量则是可以变化的值,变量就像一个模型,当你声明一个变量时,你就有了一个模型,根据不同的数据类型,你也就有不同的模型,变量里的值可以被改变,就像在一个模型里,你可以有是不同颜色,你也可以随时更换。但是不同类型的变量之间不能随意更换,就像不同类型的模型一样,你是的正方形放不进圆形的模型一样,如下图
在这里,变量就是上图里的模型,不同类型的变量就是不同的模型,下面的图形就是这些模型的数据,只有符合相应类型的模型,这些图形才能放进去,不同的颜色就是不同数值。
When the thing that your app needs to remember changes, you take the old value out of the box and put in the new value. That’s the whole point behind variables: they can vary
The size of the storage container and the sort of values the variable can remember are determined by its datatype.
在iOS里,根据变量的生命周期,可以将变量分为局部变量和实例变量。局部变量就在在某个方法内部声明,只能作用于此方法,一旦方法执行结束,这个局部变量就被销毁。实例变量则可以在一个比如视图控制器这个大类里被其类下的方法调用。一般在实例变量名称前加上下划线"_",用来区别局部变量。
下面说一下我在学这个教程时遇到的一个主要问题:在iOS8以后,苹果不再支持UIAlertView类的使用,取而代之的是UIAlertController类,而本教程使用的就是UIAlertView类,所以就需要改写alert view 的实现方法,只能使用UIAlertController类。
本教程中关于alert view 的实现方法代码是这样的:
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
// 将alert view弹出窗口显示在屏幕上
[alertView show];
//重新玩一次
[self startNewRound];
//更新标签里的数据
[self updateLabels];
在本例中,我希望在我关闭弹出来的alert窗口后,游戏界面上的数值才发生改变,而不是我点击Hit me 按钮后立即在界面上显示改变后的目标值,分数值,游戏次数等,本教程里是这样分三步实现的:
1.在BullsEyeViewController.h声明文件里在添加<UIAlertViewDelegate>
@interface BullsEyeViewController : UIViewController <UIAlertViewDelegate>
2.在showAlert动作实现代码里把delegate:nil改成delegate:self,同时移除[self startNewRound] 和 [self updateLabels]这两个方法
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:title
message:message
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
// 将alert view弹出窗口显示在屏幕上
[alertView show];
3.在.m实现文件里添加新方法- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex并将[self startNewRound] and [self updateLabels]两个方法放入其中。
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startNewRound];
[self updateLabels];
}
这里采用的是一种被称为观察者的模式(listener pattern or observer pattern),而这里的观察者listener就是delegate,通过这种监听的模式来实现这个功能的,当alert窗口要关闭时,向视图控制器发送消息说我马上要关闭了,然后在执行[self startNewRound] and [self updateLabels]这两个方法。
Delegates in three steps
Delegates are used everywhere in the iOS SDK, so it’s good to remember thatit always takes three steps to become someone’s delegate.
- You declare yourself capable of being a delegate. Here, you did that byincludingin your @interface line. This tells the compiler that the view controller can actually handle the notification messages that are sent to it.
- You let the object in question, in this case the UIAlertView, know that you wish to become its delegate. If you forget to tell the alert view that it has a delegate, then it will never send you any notifications.
- Implement the delegate methods. It makes no point to become a delegate if you’re not responding to the messages you’re being sent! Often, delegate methods are optional, so you don’t need to implement all of them. For example, UIAlertViewDelegate actually declares seven different methods but for this app you only care about alertView:didDismissWithButtonIndex:.
那么现在使用新的UIAlertController类如何实现上面这个功能的呢?
很简单,只需要一步就可以实现这个功能。
UIAlertController* alertView = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) { [self startNewRound]; [self updateLabels];}];
[alertView addAction:defaultAction];
[self presentViewController:alertView animated:YES completion:nil];
在声明UIAlertAction类里有一个Blocks对象,我把[self startNewRound] and [self updateLabels]这两个方法放到它里面,在alert view 关闭时才会会调用这两个方法。
上述解决办法主要解决这个旧版本带来的问题,但我目前对delegate机制和UIAlertController类的理解比较肤浅,有待后面的学习中深入理解,如上面理解有所错误,还望指正,谢谢!
APP开发第三步:完善功能和界面
在完成了主要功能后,可以增加能提供人性化贴心体验的功能或交互设计。本教程中讲述了如何使用自动布局,修改背景图案,图标等,讲的很详细,照着做就行了,做的多才能灵活运用!
结束语
至此,一个小游戏就开发出来了,可以玩耍下哦,是不是有点小成就感呢,呵呵,反正我照着做下来后,装在自己手机里时不时玩一下,持续燃烧着我的学习激情。
这个教程的学习方式是我所喜欢的,而且也是有效的,虽然是英文教程,但并不难理解,正好提高下英语水平嘛,不然怎么看懂苹果的官方文档。
虽然这个应用很简单,但这个过程也学了不少实用的开发知识,当然我这里还有很多内容没涉及到,那就看教程吧,毕竟我也只是简单总结下我学了这个教程后的一点理解。如有不对的地方,欢迎指正,谢谢
最后送上福利The.iOS.Apprentice.2nd.Edition
同时推荐下我正使用的PDF阅读器:PDF Expert,记笔记什么的真的很方便。
浪沙淘金,加油!