读书人

Storyboard全解析-第二一部分

发布时间: 2013-04-20 19:43:01 作者: rapoo

Storyboard全解析-第二部分

转自:http://www.iteye.com/topic/1122984

?

如果你想了解更多Storyboard的特性,那么你就来对了地方,下面我们就来接着上次的内容详细讲解Storyboard的使用方法。?

在上一篇《Storyboard全解析-第一部分》中,我们介绍了如何使用storyboard来制作多种场景和如何将这些场景链接起来,我们还学习了如何自定义一个表格视图。?

接下来这部分,也是最后一部分,我们将讲解联线(segue),静态单元格等内容,我们还将加入一个选手详细内容页面,和一个游戏选择页面。?



Segues的介绍?

现在,让我们创建一个场景使用户可以自己增加新的选手进入列表。?

在Players界面中拖入一个Bar Button,放置在导航栏的右侧,在属性监视器中将他的Identifier改为“add”,这样他就会显示一个加号的按钮,当用户点击这个按钮时,他就会弹出一个新的场景让用户对新的内容进行编辑或添加。?

在编辑器中拖入一个新的Table View Controller,放置在Players场景的右边,然后按住ctrl,拉动加号键到新的场景中,这样,这个场景就会自动和这个按钮建立联系,从而自动归入Navigation View Controller中。?
Storyboard全解析-第二一部分?
放开鼠标之后,会出现如下选项:?
Storyboard全解析-第二一部分?
选中Modal,你可以注意到出现了一种新的箭头形式:?
Storyboard全解析-第二一部分?
这种链接形式被官方称为segue(pronounce: seg-way),我叫它联线,(其实是转换的意思)这种形式的联线是表示从一种场景转换到另外一种场景中,之前我们使用的连接都是描述一种场景包含另一种场景的。而对于联线来说,它会改变屏幕中显示的内容,而且必须由交互动作触发:如轻点,或其他手势。?

联线真正了不起的地方在于:你不再需要写任何代码来转入一个新的场景,也不用在将你的按钮和IBAction连接到一起,我们刚才做的,直接将按钮和场景链接起来,就能够完成这项工作。?

运行这个app,按下 + 键,会发现出现了一个新的列表。?
Storyboard全解析-第二一部分?
这种叫做 “modal” segue(模态转换),新的场景完全盖住了旧的那个。用户无法再与上一个场景交互,除非他们先关闭这个场景,过一会我们会讨论 push segue,这种segue会把场景推入导航栈。?

新的场景现在还没有什么用,你甚至不能把他关闭呢。?

联线只能够把你送到新的场景,你要是想回来,就得使用delegate pattern,代理模式。我们必须首先给这个新的场景设置一个独有的类,新建一个继承UITableViewController的类,命为PlayerDetailsViewController。?

为了把它和storyboard相连,回到MainStoryBoard,选择新建的那个Table View Contrller,将他的类设置喂PlayerDetailViewController,千万不要忘记这一步,这很重要。?

做完这一步之后,把新场景的标题改为“Add Player”,分别加入“Done”和“Cancel”两个导航栏按钮。?
Storyboard全解析-第二一部分?
修改PlayerDetailsViewController.h 如下:?
Java代码??Storyboard全解析-第二一部分
  1. @class?PlayerDetailsViewController;??
  2. ??
  3. @protocol?PlayerDetailsViewControllerDelegate?<NSObject>??
  4. -?(void)playerDetailsViewControllerDidCancel:??
  5. ??(PlayerDetailsViewController?*)controller;??
  6. -?(void)playerDetailsViewControllerDidSave:??
  7. ??(PlayerDetailsViewController?*)controller;??
  8. @end??
  9. ??
  10. @interface?PlayerDetailsViewController?:?UITableViewController??
  11. ??
  12. @property?(nonatomic,?weak)?id?<PlayerDetailsViewControllerDelegate>?delegate;??
  13. ??
  14. -?(IBAction)cancel:(id)sender;??
  15. -?(IBAction)done:(id)sender;??
  16. ??
  17. @end??

这会声明一个新的代理机制,当用户点击Cancel或者done按钮时,我们将用它来交互Add Player场景和主场景通讯。?

回到故事版编辑器,将Cancel和Done按钮分别与动作方法连接,一种方式是,按住Ctrl拖动到ViewController上,之后选择正确的动作。?
Storyboard全解析-第二一部分?
在 PlayerDetailsViewController.m,加入如下代码:?
Java代码??Storyboard全解析-第二一部分
  1. -?(IBAction)cancel:(id)sender??
  2. {??
  3. ????[self.delegate?playerDetailsViewControllerDidCancel:self];??
  4. }??
  5. -?(IBAction)done:(id)sender??
  6. {??
  7. ????[self.delegate?playerDetailsViewControllerDidSave:self];??
  8. }??

这是两个导航栏按钮要使用的方法,现在只需要让代理知道我们刚才加入了代码,而真正关闭场景只是代理的事情。?

一般来说一定要为代理制定一个对象参数,这样他才知道向那里发送信息。?

不要忘记加入Synthesize语句。?
Java代码??Storyboard全解析-第二一部分
  1. @synthesize?delegate;??

现在我们已经为PlayerDetailsViewController设置了一个代理协议,我们需要将这个协议的实现方法(implement)写在什么地方,很明显应该写在PlayerViewController因为这个vc代表了Add Player场景。在PlayersViewController.h中加入如下代码:?
Java代码??Storyboard全解析-第二一部分
  1. #import?"PlayerDetailsViewController.h"??
  2. ??
  3. @interface?PlayersViewController?:?UITableViewController?<PlayerDetailsViewControllerDelegate>??

并在PlayersViewController.m的结尾加入:?
Java代码??Storyboard全解析-第二一部分
  1. #pragma?mark?-?PlayerDetailsViewControllerDelegate??
  2. ??
  3. -?(void)playerDetailsViewControllerDidCancel:??
  4. ??(PlayerDetailsViewController?*)controller??
  5. {??
  6. ????[self?dismissViewControllerAnimated:YES?completion:nil];??
  7. }??
  8. ??
  9. -?(void)playerDetailsViewControllerDidSave:??
  10. ??(PlayerDetailsViewController?*)controller??
  11. {??
  12. ????[self?dismissViewControllerAnimated:YES?completion:nil];??
  13. }??

目前这个代理方法只能够跳转到这个新的场景中,接下来我们来让他做一些更为强大的事情。?

iOS 5 SDK中新添加的dismissViewControllerAnimated:completion: 方法可以被用来关闭一个场景。?

最后还有一件事情需要做,就是Players场景需要告诉PlayerDetailsVC他的代理在哪里,听上去这种工作在故事版编辑其中一拖就行了,实际上,你得使用代码才能完成。?

将以下方法加入到 PlayersViewController 中?
Java代码??Storyboard全解析-第二一部分
  1. -?(void)prepareForSegue:(UIStoryboardSegue?*)segue?sender:(id)sender??
  2. {??
  3. ????if?([segue.identifier?isEqualToString:@"AddPlayer"])??
  4. ????{??
  5. ????????UINavigationController?*navigationController?=??
  6. ??????????segue.destinationViewController;??
  7. ????????PlayerDetailsViewController??
  8. ??????????*playerDetailsViewController?=??
  9. ????????????[[navigationController?viewControllers]??
  10. ??????????????objectAtIndex:0];??
  11. ????????playerDetailsViewController.delegate?=?self;??
  12. ????}??
  13. }??

当使用Segue的时候,就必须加入这个名叫 prepareForSegue 的方法,这个新的ViewController在被加载的时候还是不可见的,我们可以利用这个机会来向他发送数据。?

请注意,这个segue的最终目标是Navigation Controller,因为这个是我们链接在导航栏上的按钮,为了获取PlayerDetailsViewController实例,我们必须通过NavController的属性来获取。?

试着运行一下这个应用,单击 + 键,然后试着关闭Add Player场景,仍然不管用。?

这是因为我们没有给Segue指定一个identifier,而parepareForSegu需要检查AddPlayer的身份证,这是必须的,因为你有可能会同时使用多个联线。?

为了解决这个问题,进入Storyboard的编辑器,点击Players场景和NavgationViewController场景之间的联线,你会注意到与这个连线相关的按钮会自动亮起来。?

在属性监视器中,将Identifier设置喂“AddPlayer”?
Storyboard全解析-第二一部分?
如果这是你再次运行这个应用,点击“Cancel”或者“Done”按钮,这个场景就会自动关闭并且返回到上一级场景。?

注意:从modal场景调用dismissViewControllerAnimated:completion方法是我们在这里使用的,但是这并不意味着你必须这样做。但是,如果你不是代理来完成这个关闭窗口的工作的话,唯一需要注意的是,如果你之前使用了[self.parentViewController dismissModalViewControllerAnimated:YES] 语句来关闭窗口的话,那么这个语句就不会正常工作了。?

顺便说一下,属性检查器中有一个Transition的选项,在这里你可以选择场景转换是的动画效果。?
Storyboard全解析-第二一部分?
试着运行一下,看看那种动画你最喜欢吧,但事情不要改变Style这个选项,如果你改变了,这个app可能会crash哦。?

我们接下来在这个教程中还会用到几次代理方法,下面我们来列一下为了完成一个连线,你需要做的几件事情。?

读书人网 >移动开发

热点推荐