现在的位置: 首页 > 综合 > 正文

创建一个简单的 iOS 5 iPhone App 教程

2018年02月14日 ⁄ 综合 ⁄ 共 8462字 ⁄ 字号 评论关闭

这篇文章是“初学者怎样创建一个简单的iphone应用之三段论”系列的最后一部分。而且这个应用恰好是给吓人的虫子评判吓人级别!

在这个系列的第一部分,我们在表格视图里创建了一个含有一系列虫子的应用。

在这个系列的第二部分,我们涉及到如何给这些虫子创建一个详细视图。

在这篇文章里,我们将要涵盖如何给我们的工程添加新的虫子,如何添加一个图标和默认图像,还有如何处理长时间的操作。

好吧,我们把这个应用重新整理一遍吧!

Alex_曰生

Alex_曰生

翻译于 8天前

0人顶

 翻译的不错哦!

添加和删除小虫

目前所有进展很好,但这不是方便使用的APP!第一件事就是任何人都想添加他们自己的小虫,为添加的唯一方法就是编写程序代码!

幸运的是,我们写我们自己的  DetailViewController 编辑小虫,使用 UITableViewController 当做RootViewController,所有的基础部分都已经就位了!我们剩下四个改动需要做,我将逐位解释它们让其更好理解:

1)建立导航条按钮

在 MasterViewController.m控件里,添加如下代码到viewDidLoad:

1 self.navigationItem.leftBarButtonItem
= self.editButtonItem;
2 self.navigationItem.rightBarButtonItem
= [[UIBarButtonItem alloc]
3     initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
4     target:self
action:@selector(addTapped:)];

在此我们在导航条里建些按钮。就像在视图控制器“标题”就是一个特殊的属性被用作导航控制器,“导航条”是它们的另一个属性。

惩罚者

惩罚者

翻译于 7天前

0人顶

 翻译的不错哦!

2) 实现表格视图:commitEditingStyle:forRowAtIndexPath

还是在MasterViewController.m里,去掉表格视 commitEditingStyle:forRowAtIndexPath 的注释,然后将内容替换成下列代码:

1 if(editingStyle
== UITableViewCellEditingStyleDelete) {       
2     [_bugs
removeObjectAtIndex:indexPath.row];
3     [tableView
deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
4 }

当用户以某种方式选择修改一行时就会调用这个函数。我们检查用户是否尝试着去删除这行,如果是的话,我们就把它删了。注意,我们不仅得把它从我们的数据模型(_bugs)中移除,还得通过deleteRowsAtIndexPaths来通知表格视图其中一行已经被删除。 

3)处理添加一个新的虫子

接下来把这个方法添加到MasterViewController.m:

01 -
(
void)addTapped:(id)sender
{
02     ScaryBugDoc
*newDoc = [[ScaryBugDoc alloc] initWithTitle:@
"New
Bug"
rating:0
thumbImage:nil fullImage:nil];
03     [_bugs
addObject:newDoc];
04   
05     NSIndexPath
*indexPath = [NSIndexPath indexPathForRow:_bugs.count-1 inSection:0];
06     NSArray
*indexPaths = [NSArray arrayWithObject:indexPath];   
07     [self.tableView
insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];
08   
09     [self.tableView
selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
10     [self
performSegueWithIdentifier:@
"MySegue"sender:self];   
11 }

我们在第一步把东西都设置好,这样的话当用户点击添加按钮的时候,这个方法就被调用了。

在这里,我们创建一个含有一些自定义值的ScaryBugDoc,然后将它添加到bugs数组里去。注意到我们还得同时更新表格视图,这样才知道有新的行添加了进去。

然后我们调用一些代码来实现表格视图好像作为用户来选择新的行,这样呢我们就可以立即去给新添加的虫子编辑视图。我们首先选择在表格视图里的行,然后我们手动完成在Storyboard编辑器里的segue。

注意,我们实际上从不在Storyboard里命名segue为 “MySegue” ,这样的话,那就让我们在最后一步来这么做吧。

Alex_曰生

Alex_曰生

翻译于 6天前

0人顶

 翻译的不错哦!

4) 命名segue

打开MainStoryboard.storyboard,然后点击在master和detail view controller之间的箭头---这就是你的segue。

然后,在侧边栏(属性查看器)的第四个选项卡上,设置mySegue的标示符。这样的话,我们就可以当我们在代码中想要它时手动地运行它。

好了,就是这样。如果你编译、运行这些代码,你应该可以添加你自己的虫子了,比如下面这个:

Alex_曰生

Alex_曰生

翻译于 6天前

0人顶

 翻译的不错哦!

添加一个图标和默认图像

好的,我们的app现在看起来很好玩了。让我们继续,让它变得更加丰富多彩吧!

如果我们现在就开始的话,那就会出现很尴尬的情况,我的意思是说我们现在连一个图标都木有!

幸运的是,这个问题很好解决。起初,我们从ExtraStuffForScaryBugs2.zip压缩文件包中添加了一个图标到我们的工程文件里(logo1.png)。我们就把这个设置为我们的工程图标吧!

要达到这个目标,最简单的方法就是在工程导航栏中选择你的ScaryBugs工程,然后选择你的ScaryBugs为目标。要注意一点的是选择了Summary选项卡,然后下拉倒App Icons,按住control键并且点击第一个图标,然后点选择文件:

从你的工程目录中选择logo1.png,接受任何的警告,然后你就可以看到了。如果你得到一个警告说图像的尺寸不符合,那就裁剪logo1.png为57x57的格式大小(以前下载的文件比这个大一些)。

Alex_曰生

Alex_曰生

翻译于 5天前

0人顶

 翻译的不错哦!

注意,这是一个编辑ScaryBugs-Info.plist的快捷方式,你的app的设置就是这样存储的。你可以通过打开ScaryBugs-Info.plist来验证,你可以看到下面这个:

你可以自己手动添加这些设置到这个文件,但是我发现如果GUI可以用的时候使用GUI更简单一些。

我们继续,先删掉然后再重新安装这个app到你的模拟器上或者iphone上,然后你就可以看到新的图标了。

我们还有一个要修改的地方。如果你试图运行ScaryBugs,你也许会注意到,在你点击了图标之后,在打开app之前会出现一个黑屏。这个就有点尴尬了---因为看起来我们的app反应并不是那么好啊!

根据苹果公司的文件显示,我们最好是显示一个和你的app一样的屏幕,但是不包含任何的数据。其实这个很简单的,你打开MasterController.m,然后做下面这些改变就好了:

1 //
Replace tableView:numberOfRowsInSection's return statement to the following:
2 return 0; //return
_bugs.count;

然后在你的设备上运行这个工程,你就会在工程运行后看到一个空的表格视图。在XCode里,点击在工具条(最右边那个)上的Organizer按钮,选择你的设备,然后点屏幕截图选项卡,然后点“新建屏幕截图”(在右下角)就可以得到一张截图了。 


然后点保存为启动图像。确保你选择了ScaryBugs工作区,保持名字为默认的,然后点下一步。系统会把这个图像保存到你的工程里,然后设置它为启动图像---很实用,是吧?

你要是点击你的目标的总结选项卡,你可以看到它已经把图像设置为启动图像:


然后呢,把 tableView:numberOfRowsInSection还原到以前的样子,再运行app。你可以看到应用启动的时候出现一个默认的图像而不是一个黑框框,这样你的app看起来反应很好了。


Alex_曰生

Alex_曰生

翻译于 5天前

0人顶

 翻译的不错哦!

福利:处理长时间运行的操作

如果你在模拟器上运行这个应用,也许没任何问题,但是你如果在你的iphone上运行,你想通过点击一张图片来更换它,这将会有一个很长时间的延迟,因为UIImagePicker要初始化。在你选了一张图片后,会有另一个长时间的延迟,因为图片要调整大小(特别是当图片很大的时候)。这样的话很不好啊!这样使你的应用看起来不是能很快相应用户的操作。

其实,要记住的是主要原则是,你绝不要在主线程上出现一个长时间运行的操作。可是现在我们已经在两个地方违反了这个原则了,这就是为什么我们的应用看起来不那么很快的相应用户操作。

你需要做的是把这个长时间运行的操作放在后台线程。理想状态下,这个操作会在用户继续做其他的事的时候在后台完成。但是,如果这项工作要求在用户可以继续做其它事情之前发生(比如说装载图片选择器),那你至少也应该显示一个某种表示正在装载的图标,这样的话用户就能明白这个应用还在工作而不是已经崩掉了!

Alex_曰生

Alex_曰生

翻译于 5天前

0人顶

 翻译的不错哦!

好吧,这就是我们现在在这里要做的---运行这个在后台线程长时间运行的代码,然后实现在我们等待这个操作完成时,在前台主线显示一个“正在下载”的视图。

显示一个正在装载的视图这个意愿对app开发人员来说是一个很常见的问题,所以有一些人已经创建了一些活动指示库,这个可以节省我们一些自己去做的时间。我已经尝试过一部分了,我目前最喜欢的是由Sam
Vermette设计的SVProgressHUD,所以呢,我们就试试这个吧!你可以在 SVProgressHUD github主页下载一份。

当你下载完了SVProgressHUD之后,添加SVProgressHUD.h 和and SVProgressHUD.m到你的工程的下面的“视图”组。不过,你还要完成两步设置:

1.添加需要的库。在工程导航栏中点击你的工程,然后选择你的ScaryBugs为目标。选择Build Phases选项卡,然后展开连接二进制文件和库部分,点+按钮,然后添加 QuartzCore.framework.

1.没有ARC帮助的编译。SVProgressHUD目前还不兼容ARC,所以我们需要在没有ARC帮助的情况下编译它。要做到这点,我们首先展开Compile Sources选项卡,然后双击SVProgressHUD.m的进入口。输入-fno-objc-arc 到对话框里来在没有ARC帮助的情况下编译它。

2012/7/15 更新:SVProgressHUD现在已经支持ARC了,所以这步已经没有必要了。谢谢Juan指出这点!(晕,翻译到这里才发现其实这步没有必要了!)

好了,到了这里你应该能够准确无误地创建自己的项目了。

Alex_曰生

Alex_曰生

翻译于 5天前

0人顶

 翻译的不错哦!

然后的话呢,在DetailViewController.m里面做如下改变:

01 //
At top of file
02 #import
"SVProgressHUD.h"
03   
04 //
Replace addPictureTapped with the following:
05 -
(IBAction)addPictureTapped:(id)sender {
06     if(self.picker
== nil) {  
07   
08         //
1) Show status
09         [SVProgressHUD
showWithStatus:@
"Loading
picker..."
];
10   
11         //
2) Get a concurrent queue form the system
12         dispatch_queue_t
concurrentQueue =
13         dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
14   
15         //
3) Load picker in background
16         dispatch_async(concurrentQueue,
^{
17   
18             self.picker
= [[UIImagePickerController alloc] init];
19             self.picker.delegate
= self;
20             self.picker.sourceType
= UIImagePickerControllerSourceTypePhotoLibrary;
21             self.picker.allowsEditing
= NO;   
22   
23             //
4) Present picker in main thread
24             dispatch_async(dispatch_get_main_queue(),
^{
25                 [self.navigationController
presentModalViewController:_picker animated:YES];   
26                 [SVProgressHUD
dismiss];
27             });
28   
29         });       
30   
31     }  else{       
32         [self.navigationController
presentModalViewController:_picker animated:YES];   
33     }
34 }

现在这里有很多好的主意。那我们就一部分一部分来看看吧。 

1.这里我们用了我们添加的SVProgressHUD帮助类到屏幕来展示一个有旋转效果的“正在下载”的GUI。这样的话,用户就会知道应用正在完成某项工作而不是已经卡住了。

2.我们想要在后台下载这个图片选择器。你可以在iOS平台用一个叫做 Grand Central Dispatch的技术做到这点。我们在这儿就不一一说了(但是如果你感兴趣的话,那你看看这个教程)。现在开始呢,你所需要知道的就是这条线给你一个你可以在后台运行一大段代码的队列。

3.这条线在后台运行了一大段代码来下载图像选择器。如果你对这段代码的语法感到困惑的话,你看看这个教程

4.最后,我们在主队列上展示了这个选择器。注意,你一定要经常在主队列上更新你的GUI---你不能在后台线程做到这点。

类似的,我们同样可以在后台实现调整图片大小。把imagePickerController:didFinishPickingMediaWithInfo 替换为下面这个:

01 -
(
void)imagePickerController:(UIImagePickerController
*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {   
02   
03     [self
dismissModalViewControllerAnimated:YES];
04   
05     UIImage
*fullImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
06   
07     //
1) Show status
08     [SVProgressHUD
showWithStatus:@
"Resizing
image..."
];
09   
10     //
2) Get a concurrent queue form the system
11     dispatch_queue_t
concurrentQueue =
12     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
13   
14     //
3) Resize image in background
15     dispatch_async(concurrentQueue,
^{
16   
17         UIImage
*thumbImage = [fullImage imageByScalingAndCroppingForSize:CGSizeMake(44, 44)];
18   
19         //
4) Present image in main thread
20         dispatch_async(dispatch_get_main_queue(),
^{
21             self.detailItem.fullImage
= fullImage;
22             self.detailItem.thumbImage
= thumbImage;
23             self.imageView.image
= fullImage;
24             [SVProgressHUD
dismiss];
25         });
26   
27     });
28   
29 }

这就是了!在你的设备上运行一下试试看,你将会发现在这个长时间运行的工作发生的时候会有一个新的动画效果,这使得你的app会有一个更好的用户体验。 


Alex_曰生

Alex_曰生

翻译于 5天前

0人顶

 翻译的不错哦!

下一步我们要做什么呢?

这里有一个工程样本,它包含了这个教程系列里的所有的代码。

祝贺你---你已经完成了为你的iOS创建一个简单的Master/Detail 应用了!你已经通过了一个整合你的应用的分部课程了,你也可以发掘更多这个领域的更多知识。

下面是我建议你对的文章:

  • The
    iOS Apprentice
    :iOS辅导团队成员Matthijs Hollemans已经写了一个详细的给iOS开发初学者的教程系列,它包含了几乎所有作为开发者你需要知道的东西,从最基本的开始。你可以通过注册iOS信息月刊免费下载到第一部分,或者你可以在raywenderlich.com
    store
    购买整个系列。
  • Beginning Storyboards in iOS 5 Tutorial
    在iOS5中布局你的用户接口,你会典型地使用StoryBoard编辑器,所以这个是很必要去学一下这是怎么工作的。
  • Beginning ARC in iOS 5 Tutorial: 明白在iOS5中内存管理是怎样处理的同样也是很重要的(用ARC是很简单的)。
  • How To Use Blocks in iOS 5 Tutorial:如果你对于块是新手,那你应该看看这个课程辅导。它同时给你一些额外的Storyboard的练习。
  • Multithreading
    and Grand Central Dispatch on iOS
    : 学习怎么在后台运行任务来保持你的应用及时响应同样很重要。这个课程主要讲了这个,但是你应该在这个网站上看更多的细节。
  • How To Submit
    Your App to the App Store:
    当然,当你完成你的app后,你会想要知道怎么把你的app提交到App Store!读读这篇教程吧,这里面会一步步教你怎么做。
  • And much more! 我们在这个网站上还有很多关于iOS的教程。点这个链接查看所有的课程列表吧。

我祝你在你的iOS开发之路上一路顺风,也希望你喜欢这个ScaruBugs应用!如果你有任何问题或者想法,请加入到我们的论坛来讨论!

(翻译到最后,我希望大家最好还是多学点英文,看原版的教程比较好,毕竟编程这种东西,还是老外的很多东西很有价值。本人翻译水平有限,只能给你们一个大意,还望谅解!有兴趣的朋友可以关注我新浪微博@Alex曰生,可以一起讨论英语学习或者计算机方面的东西。)

抱歉!评论已关闭.