iOS 7在右侧添加了幻灯片,可以将视图控制器从堆栈中弹出。是否可以通过向左滑动将其添加回去?

时间:2013-12-01 04:03:54

标签: ios objective-c uinavigationcontroller ios7

嗯,技巧问题,我知道这是可能的,因为有一些应用程序在做,特别是Reeder做得很好。

在Reeder中,似乎弹出的视图控制器不会从内存中删除,或者不管是什么典型行为,因为在弹出并返回到上一个视图控制器后,您可以从右向左滑动以查看一点点,如果你在离开之前滚动前一个视图控制器,你仍然可以看到滚动发生。这种快速跳回到您正在查看的先前视图控制器的能力,无需从头开始预加载,这正是我正在寻找的。

基本上,在iOS 7中默认情况下,当您从视图控制器的左边缘向右滑动时,它会将其弹出导航堆栈。我喜欢能够从右边缘向左滑动以将其添加回来。可以想象,在Web浏览器中,您可以在按下后单击“前进”按钮。 (或者在iOS 7的Safari中你可以做到这一点。)

默认情况下,此功能是否是iOS 7的一部分,我找不到它?或者有没有关于如何完成它的信息?

4 个答案:

答案 0 :(得分:8)

选项取决于您尝试支持的iOS版本。

  1. 在iOS 7+中,您可以使用自定义视图控制器转换并实现交互式视图控制器转换。有关概念性描述,请参阅WWDC 2013视频Custom Transitions Using View Controllers。基本过程是:

    • 创建一个动画控制器,用于定义动画的内容。动画控制器是符合UIViewControllerAnimatedTransitioning的对象。 (注意,必须为标准的推送动画定义自定义动画控制器似乎很奇怪,但是在下面你会看到我们想要一个手势识别器与交互控制器交互,但是你不能定义一个自定义交互控制器如果您还没有定义自定义动画控制器。)

    • 实例化交互控制器。您可以创建符合UIViewControllerInteractiveTransitioning的自己的交互控制器类,但最简单的方法是简单地实例化UIPercentDrivenInteractiveTransition对象。

    • 现在您已拥有交互控制器,您可以将手势识别器(例如UIScreenEdgePanGestureRecognizer)链接到它。手势识别器将调用调用交互控制器的updateInteractiveTransition来指定动画的进度,因为它对应于连续手势。

    • 显然,如果您要识别从右边缘滑动到特定场景的“推动”,那么您将跟踪“下一个”场景将会是什么。有时你会有一系列预定义的视图控制器。有时您只需保留一堆先前从中弹出的视图控制器,以便您可以从右侧滑动以将其重新打开。它只取决于所需的用户体验。

    iOS 7客户转换提供了令人难以置信的控制,可以自定义与交互式转换相关联的动画和手势。但要做到这一点需要做一些工作。

  2. 如果您只是想在一系列视图控制器之间轻松进行幻灯片切换,则可以使用UIPageViewController。在iOS 6及更高版本中,您可以使用transitionStyle UIPageViewControllerTransitionStyleScroll。 (不幸的是,在iOS 5中,您只有页面卷曲过渡。)

  3. 在iOS 5+及更高版本中,您也可以使用自定义容器控制器自己执行此操作,手动添加子视图控制器视图,在手势期间更改帧。显然,您也必须执行所有自定义容器调用(例如addChildViewControllerremoveChildViewControllerwillMoveToParentViewControllerdidMoveToParentViewController等。请参阅 View Controller编程指南的WWDC 2011视频Implementing UIViewController ContainmentCreating Custom Container View Controllers部分。

答案 1 :(得分:2)

我要做的是创建一个UINavigationController的自定义子类,并给它一个(强)属性lastPoppedVC。然后覆盖popViewControllerAnimated的实现,以保存正在弹出到lastPoppedVC的视图控制器。

还设置了一个滑动手势识别器,用于从左侧滑动手势,将lastPoppedVC推回到堆栈。这需要一些修改,因为我认为你不能将手势识别器附加到导航控制器的内容视图。您可能需要将手势识别器附加到您推送到自定义导航控制器堆栈的每个VC上,并设计一种触发“推回”的方法。 (您可能希望创建一个具有handleSwipeFromLeftGesture方法的UIViewController类别,该方法将消息发送给拥有的导航控制器。)

答案 2 :(得分:2)

动画本身没问题。这是代码,如果你从右边拖动另一个视图控制器的视图来自右边。这是一个标签栏控制器,而不是导航控制器,但所涉及的原则完全相同:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch06p296customAnimation2/ch19p620customAnimation1/AppDelegate.m

因此,从右侧拖动以引入另一个视图控制器视图的手势非常简单。

唯一的问题是解释右边的拖拽意味着逻辑的问题。在我刚刚指出的代码中,很清楚左侧或右侧的拖动是什么意思:它意味着“切换到视图控制器的左侧/右侧,如果有的话”(在标签栏控制器中) ) - 我已经提供了逻辑来使它做到这一点。好吧,在导航控制器的情况下,很清楚从左侧拖动意味着什么:“返回”。但我无法想象当用户从右侧拖动时,您期望将哪个视图控制器压入堆栈;你必须提供逻辑来以某种方式指定。

答案 3 :(得分:0)

我有一个创造性的解决方案。

为您的视图控制器创建一个NSIndexPath对象(例如NSIndexPath *previousIndexPath),它将存储最后一个viewControllerPushed的indexPath

每次推送新的视图控制器时都会更新它  (使用-didSelectRowAtIndexPath-prepareForSegue方法) 所以当你使用UIScreenEdgePanGestureRecognizer时, 您可以直接触发[self didSelectRowAtIndexPath:previousIndexPath]