使用segue来定义应用界面流。Segue定义了应用storyboard文件中两个视图控制器之间的过渡。Segue的起点是按钮、表格行或者发起segue手势识别器。Segue的终点是你希望显示的视图控制器。Segue总是present新视图控制器,但你还可以使用一个unwind segue来dismiss视图控制器。
你不需要以编程的方式触发segue。在运行时,UIKit加载视图控制器相关的segue并连接它们到相应的元素。当用户与元素交互,UIKit加载适当的视图控制器,通知你的应用将发生segue,执行过渡。你可以使用UIKit发送通知,将数据传递给新视图控制器或防止segue发生。
创建视图控制器之间的segue
在同一storyboard文件中的视图控制器之间创建segue,点击第一个视图控制器的适当元素并按住Control键,拖到目标视图控制器。Segue的起点必须是一个视图或对象,有定义好的动作,如控件、按钮或手势识别器。你还可以在基于cell的视图如table和collection视图上创建segue。图9-2 展示了如何创建segue,当点击表格某行显示新视图控制器。
注意
某些元素支持多个segue。例如,表格行允许你配置不同的segue用于行accessory按钮不同的点击、其他行的点击。
当你释放鼠标按钮时,界面构建器将提示你选择两个视图控制器间的关系,如图9-3所示。选择segue对应的过渡。
当选择segue的关系类型,尽量选择自适应segue。自适应segue会自动根据当前环境调整自己的行为。例如,一个show类型的segue的行为基于present的视图控制器。提供非自适应segue的app必须运行在iOS7上,iOS7不支持自适应segue。图9-1列出了自适应segue以及他们在应用中的表现。
Segue类型 | 行为 |
---|---|
Show (Push) | 这个segue使用目标视图控制器的showViewController:sender: 方法显示新内容。对于大多数视图控制器,该segue以模态的方式present新视图控制器到源视图控制器上。一些视图控制器重写该方法,用它来实现不同的行为。例如,导航控制器push新视图控制器到其导航堆栈上。UIKit使用showViewController:sender: 方法定位源视图控制器。 |
Show Detail (Replace) | 该sugue使用目标视图控制器的showDetailViewController:sender:方法显示新内容。该segue只用于嵌入到 UISplitViewController对象的视图控制器。有了该segue,分屏视图控制器用新内容代替其第二个子视图控制器(详细视图控制器)。大多数其他视图控制器以模态的方式present新内容。UIKit使用 targetViewControllerForAction:sender:方法定位源视图控制器。 |
Present Modally | 该segue使用指定的present和过渡风格,以模态方式显示视图控制器。视图控制器定义适当的present环境处理实际present。 |
Present as Popover | 在水平常规环境中,视图控制器以弹窗的形式出现。在水平紧凑环境中,全屏present视图控制器。 |
表9-1 自适应segue类型
在创建segue后,选择segue对象并使用属性检查器分配一个标识符。在segue期间,你可以使用标识符来确定触发那个segue,如果你的视图控制器支持多个segue,这个方法特别有用。标识符包含在UIStoryboardSegue对象中,当执行segue时,会传递给你的视图控制器。
在运行时修改一个segue的行为
图9-4显示了当触发segue时发生了什么。大部分工作发生在presenting视图控制器中,该视图控制器负责到新视图控制器。新视图控制器的配置基本遵循相同的步骤,如同你自己创建新视图控制器并present。因为segue都在storyboard中配置,segue涉及的两个视图控制器必须在同一个storyboard。
在segue期间,UIKit调用当前视图控制器的方法来影响segue结果。
- shouldPerformSegueWithIdentifier:sender:方法让你可以组织segue发生。该方法返回NO会导致segue失败但并不阻止其他行为的发生。例如,点击表中的行仍然会导致表调用代理相关方法。
- 源视图控制器的 prepareForSegue:sender: 方法让你可以传递源视图控制器的数据到目标视图控制器。传递到该方法的UIStoryboardSegue对象包含目标视图控制器的引用以及其他segue相关的信息。
创建一个unwind segue
unwind segue可以dismiss已present的视图控制器。在界面构建器中,通过链接按钮或其他合适的对象到当前视图控制器Exit对象上创建unwind segue。当用户点击该按钮或界面上适当对象,UIKit在视图控制器层级上搜索能处理unwind segue的对象。然后它dismiss当前视图控制器和任何显示unwind segue目标的中间视图控制器。
创建unwind segue
- 在unwind segue的末端选择要在屏幕上显示的视图控制器。
- 在你选择的视图控制器中定义一个unwind动作方法。
该方法的swift语法如下:
<pre><code>
@IBAction func myUnwindAction(unwindSegue: UIStoryboardSegue)
</pre></code>
该方法的Objective-C语法如下:
<pre><code>- (IBAction)myUnwindAction:(UIStoryboardSegue*)unwindSegue</pre></code>
- 导航到启动unwind动作的视图控制器上。
- Control-click启动unwind segue的按钮(或其他对象)。该元素必须在你希望dismiss 的视图控制器上。
- 拖动到视图控制器场景顶部的Exit对象。
- 在关系面板上选择unwind动作方法。
试图在界面构建器上创建相应的unwind seuge之前,必须在视图控制器上定义一个unwind 动作方法。该方法是必须的,告诉界面构建器有unwind segue有一个有效的目标。
使用unwind 动作方法的实现来执行app的特定任务。你不需要dismiss任何参与segue的视图控制器;UIKit为你做了。相反,使用segue对象可以获取被dismiss的视图控制器,这样你可以检索数据。还可以使用unwind动作在unwind segue完成前更新当前视图控制器。
以编程的方式启动segue
segue经常因为storyboard文件中创建的连接而触发。然而,有些时候你不能在storyboard中创建segue,可能因为目标视图控制器没有确定。例如,一个游戏应用可能根据游戏结果过渡到不同界面。在这些情况下,你可以使用当前视图控制器的 performSegueWithIdentifier:sender:方法,以编程的方式触发segue。
列表9-1展示了从竖屏旋转到横屏时,present特定视图控制器的segue。因为在这种情况中,通知对象没有提供有用的信息来执行segue命令,视图控制器指定自己作为segue的sender。
列表9-1 以编程的方式触发segue
<pre><code>- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView) {
[self performSegueWithIdentifier:@"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
// Remainder of example omitted.
}
// Remainder of example omitted.
}
</pre></code>
创建自定义segue
界面构建器提供segue的标准用法:从一个视图控制器到另一个视图控制器的过渡或者在presenting视图控制器上以弹窗的方式显示控制器。然而,如果segue不满足你的需求,你可以创建一个自定义segue。
segue生命周期
了解如何自定义segue,你需要理解segue对象的生命周期。segue对象是UIStoryboardSegue类实例或其子类。应用不要直接创建segue;当触发sugue时UIKit会创建该对象。
- 创建和初始化presented视图控制器。
- 创建segue对象并调用其 initWithIdentifier:source:destination: 方法。在界面构建器中设置segue的标识符是唯一的字符串,另外两个参数代表了过渡中的两个视图控制器对象。
- 调用presenting视图控制器的 prepareForSegue:sender: 方法,参见运行时修改segue行为( Modifying a Segue’s Behavior at Runtime)。
- 调用segue对象的 perform方法。该方法执行一个过渡到新视图控制器。
- segue对象的引用被释放。
实现自定义segue
实现一个自定义segue,继承 UIStoryboardSegue
并实现以下方法:
- 覆盖
initWithIdentifier:source:destination:
方法并用它来初始化自定义segue对象。总是要先调用super方法。 - 实现perform方法并用它来配置过渡动画。
注意
如果实现添加属性来配置segue,你不能在界面构建器中配置这些属性。相反,可以在触发segue的源视图控制器的 prepareForSegue:sender: 方法中配置自定义segue的附加属性。
列表9-2展示了一个非常简单的自定义segue。这个例子简单的present目标视图控制器而没有任何形式的动画,但你可以扩展实现自己的动画。
列表9-2 自定义segue
<pre><code>- (void)perform {
// Add your own animation code here.
[[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:nil];
}
</pre></code>