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

Posted

技术标签:

【中文标题】iOS 7 在右侧添加了滑动以将视图控制器从堆栈中弹出。是不是可以通过向左滑动将其添加回来?【英文标题】:iOS 7 added slide to the right to pop a view controller off the stack. Is it possible to add it back by sliding left?iOS 7 在右侧添加了滑动以将视图控制器从堆栈中弹出。是否可以通过向左滑动将其添加回来? 【发布时间】:2013-12-01 04:03:53 【问题描述】:

好吧,诡计问题,我知道这是可能的,因为有一些应用程序可以做到这一点,特别是 Reeder 做得很好。

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

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

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

【问题讨论】:

你是怎么解决这个问题的? @StianHøiland 我还没有。当我需要解决这个问题时,我正在考虑在不久的将来为此增加赏金。 【参考方案1】:

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

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

    创建一个动画控制器来定义动画是什么。动画控制器是一个符合UIViewControllerAnimatedTransitioning 的对象。 (注意,必须为像推送动画这样标准的东西定义自定义动画控制器似乎很奇怪,但在下面你会看到我们希望手势识别器与交互控制器交互,但你不能定义自定义交互控制器如果您还没有定义自定义动画控制器。)

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

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

    显然,如果您要将右边缘的滑动识别为对特定场景的“推动”,那么您将跟踪“下一个”场景将是什么。有时你会有一系列预定义的视图控制器。有时你会保留一堆你之前弹出的视图控制器,这样你就可以从右边滑动来推回它们。这仅取决于所需的用户体验。

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

    如果您只是在寻找一种更简单的方法来在一系列视图控制器之间进行滑动转换,您可以使用UIPageViewController。在 iOS 6 及更高版本中,您可以使用 transitionStyleUIPageViewControllerTransitionStyleScroll。 (不幸的是,在 iOS 5 中,您只有页面卷曲过渡。)

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

【讨论】:

我非常感谢这个答案。 iOS 7 视图控制器转换提供了很大的帮助,但我仍然觉得这里我缺少一些东西,需要的不仅仅是视图控制器转换。 @DougSmith 我不确定您认为缺少 iOS 7 自定义视图控制器转换的哪一部分,但我尝试更新我的答案,列举了一些涉及的移动部分。跨度> 【参考方案2】:

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

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

【讨论】:

+1 或者,我使用了NSMutableArray 的弹出视图控制器,因此您可以弹出多个级别。【参考方案3】:

动画本身没有问题。这是代码,如果您从右侧拖动另一个视图控制器的视图从右侧进入。这是一个标签栏控制器,不是导航控制器,但是涉及的原理是完全一样的:

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

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

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

【讨论】:

链接好像移到了github.com/mattneub/Programming-iOS-Book-Examples/blob/master/… @bcattle 是也不是。否,因为该示例已更新到 iOS 8 和 Swift,此处:github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…【参考方案4】:

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

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

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

【讨论】:

我很抱歉。我显然在回答中做了很多假设。然而,前提仍然存在。通过创建每次推送新视图控制器时更新的属性,您可以存储重新调用视图控制器推送所需的所有信息。注意:这将重新加载视图控制器,而不是将其恢复到之前弹出时的状态。

以上是关于iOS 7 在右侧添加了滑动以将视图控制器从堆栈中弹出。是不是可以通过向左滑动将其添加回来?的主要内容,如果未能解决你的问题,请参考以下文章

IOS如何为UICollectionView的第一个单元格设置动画以从右侧滑入

从导航堆栈中弹出视图控制器时从右侧滑入

iOS 7:在底部导航栏的表格视图之间滑动

在 iOS 7 中默认情况下,从表格视图中打开一个横向视图确实选择了行

模态segue推动顶部的附加导航栏滑动

iOS 7 中的 iOS 6 滑动推送控制器动画