向下拖动以关闭ViewController

时间:2021-08-31 11:20:40

I'm building an app with an MKMapView as background, and I would like to have a "slide-up/down"-view, just like in Google Maps or Spotify (example.gif), that can be dismissed by dragging it down.

我正在构建一个以MKMapView为背景的应用程序,我希望有一个“向上/向下”视图,就像在谷歌地图或Spotify(example.gif)中一样,可以通过拖动它来解除它。

The 'slide-up/down-view' will hold quite a lot of info, including a UITableView, so I would probably like it to have its own ViewController, instead of just a UIView alone. What could be a good approach for this?

'上滑/下滑'将包含很多信息,包括UITableView,所以我可能希望它拥有自己的ViewController,而不仅仅是一个UIView。对此有什么好处?

Is it possible "just" to add a childViewController/ContainerView and give it a UIPanGestureRecognizer? All help is appreciated!

可以“只”添加一个childViewController / ContainerView并给它一个UIPanGestureRecognizer吗?所有帮助表示赞赏!

1 个解决方案

#1


8  

These view controller transitions are, sigh, unfortunately very complicated to do but there are lots of good tutorials online about them. You are correct in putting the subview into its own view controller. There are several other moving parts required. Fully detailing them would be enough material to write a book on the topic, but the high level overview is this:

不幸的是,这些视图控制器转换是非常复杂的,但是有许多关于它们的在线教程。将子视图放入自己的视图控制器中是正确的。还需要其他几个运动部件。完全详细说明它们就足以写一本关于这个主题的书,但高级概述是这样的:

Chapter 1: The Container

Think of the view controller with the map view as view controller A. Think of the slide-up/down view as view controller B. We want to transition seamlessly from A to B (and B to A). Cocoa provides an API for doing this, but first you'll need a container view controller that contains both A and B as a child view controller. This could be a navigation controller or your own custom container controller.

将视图控制器与地图视图视为视图控制器A.将上滑/下移视图视为视图控制器B.我们希望从A无缝过渡到B(和B到A)。 Cocoa提供了一个用于执行此操作的API,但首先您需要一个包含A和B作为子视图控制器的容器视图控制器。这可以是导航控制器或您自己的自定义容器控制器。

Chapter 2: Noninteractive Custom Container View Controller Transition

Once you have the container view controller, code it up so that you can go from A to B and back by pressing a button. (Throw a debug button somewhere into your app.) So you tap a button and you go from A to B and then you tap it again to go from B to A. To do this, there are the noninteractive custom container view controller transition APIs (it's a mouthful). This will require implementing an animation controller and a transitioning delegate, as detailed in that excellent objc.io tutorial and its corresponding GitHub repository.

拥有容器视图控制器后,对其进行编码,以便按A按钮从A到B再返回。 (在你的应用程序的某个地方放一个调试按钮。)所以你点击一个按钮然后从A转到B然后再次点击它从B转到A.为此,有非交互式自定义容器视图控制器转换API (这是一口)。这将需要实现动画控制器和转换委托,详见优秀的objc.io教程及其相应的GitHub存储库。

Chapter 3: Interactive Custom Container View Controller Transition

But, of course, you want users to swipe up and down to trigger the transition. This will take you into the world of interactive blah blah blah APIs, where you implement an interaction controller and connect it to a pan gesture recognizer. The corresponding GitHub repository to that blog post actually uses a pan gesture like you would. This is particularly finicky work, as you would want the transition to be canceled should the user decide to stop panning midway through, but all that is detailed in the code and article.

但是,当然,您希望用户上下滑动以触发转换。这将带您进入交互式blah blah blah API的世界,您可以在其中实现交互控制器并将其连接到平移手势识别器。该博客文章的相应GitHub存储库实际上使用了像您一样的平移手势。这是特别挑剔的工作,因为如果用户决定在中途停止平移,您会希望取消转换,但所有这些都在代码和文章中详细说明。

Chapter 4: View Sharing

I'm actually not sure what this is called. The problem here is that you want the Google Maps / Spotify look and feel where a part of view controller B's view actually is visible while you're in view controller A. And the pan gesture recognizer is attached to B's view so that when you slide it up, B's view gets bigger and bigger until the interactive animation finishes and you've transitioned from A to B. Is there a good tutorial on this? I haven't found one, but it's becoming more and more common as an iOS UX idiom.

我其实不确定这叫什么。这里的问题是,当您在视图控制器A中时,您希望Google Maps / Spotify外观和视觉控制器B的视图的一部分实际可见。并且平移手势识别器附加到B的视图,以便在您滑动时B,视图越来越大,直到交互式动画结束,你已经从A转换为B.是否有一个很好的教程?我还没有找到一个,但它作为一个iOS用户界面的习惯用法变得越来越普遍。

I myself have a small demo project illustrating how to do this. What I do is I have a navigation controller as my container view controller. The navigation controller's root view controller is my home view controller (view controller A). In view controller, I have view controller B as a child. So that's navigation controller owns A owns B.

我自己有一个小型的演示项目,说明如何做到这一点。我所做的是我有一个导航控制器作为我的容器视图控制器。导航控制器的根视图控制器是我的主视图控制器(视图控制器A)。在视图控制器中,我将控制器B视为孩子。因此,导航控制器拥有A拥有B.

When the user taps on B, I push B onto the navigation stack, thus reparenting it. At that point, my noninteractive animation controller kicks in as a custom navigation controller push animation. And so it looks like B is smoothly transmogrifying from its small bounds to its larger bounds. (I recommend running the xcodeproj to see the effect as I have done a terrible job of describing it.)

当用户点击B时,我将B推到导航堆栈上,从而重新显示它。那时,我的非交互式动画控制器开始作为自定义导航控制器推送动画。因此看起来B很容易从它的小边界变形到更大的边界。 (我建议运行xcodeproj来查看效果,因为我已经做了很糟糕的描述。)

This technique would work just as well for an interactive animation. As to whether it's the best technique, I think that's up for debate — there are lots of ways of doing what you see in the Google Maps and Spotify apps. Apple could certainly do a lot better job of documenting the APIs for complex, interactive animations.

这种技术对于交互式动画也同样有效。至于它是否是最好的技术,我认为这是有争议的 - 有很多方法可以做你在Google Maps和Spotify应用程序中看到的内容。苹果当然可以更好地记录复杂的交互式动画的API。

I would caution you to avoid using Auto Layout until you have your animations tweaked and ready, as it doesn't really interact well with your animation controllers. Good ol' frame rectangle math is best here until you find your bearings. Auto Layout is magic and, as you might be able to tell from how exhaustingly long this answer is, there's already enough magic to go around.

我会提醒您在调整动画并准备好动画之前避免使用自动布局,因为它与动画控制器没有很好的交互作用。好的ol'框架矩形数学在这里是最好的,直到你找到你的轴承。自动布局是神奇的,正如你可能能够分辨出这个答案有多长,这已经足够神奇了。

See Also

You can click on the purple Apple logo in the top right of asciiwwdc.com pages to watch the videos of the talks or grab the PDFs from the Resources tabs. Some of the best documentation for iOS is locked up in these WWDC talks.

您可以单击asciiwwdc.com页面右上角的紫色Apple徽标,观看会谈的视频或从“资源”选项卡中获取PDF。 iOS的一些最佳文档被锁定在这些WWDC会谈中。

#1


8  

These view controller transitions are, sigh, unfortunately very complicated to do but there are lots of good tutorials online about them. You are correct in putting the subview into its own view controller. There are several other moving parts required. Fully detailing them would be enough material to write a book on the topic, but the high level overview is this:

不幸的是,这些视图控制器转换是非常复杂的,但是有许多关于它们的在线教程。将子视图放入自己的视图控制器中是正确的。还需要其他几个运动部件。完全详细说明它们就足以写一本关于这个主题的书,但高级概述是这样的:

Chapter 1: The Container

Think of the view controller with the map view as view controller A. Think of the slide-up/down view as view controller B. We want to transition seamlessly from A to B (and B to A). Cocoa provides an API for doing this, but first you'll need a container view controller that contains both A and B as a child view controller. This could be a navigation controller or your own custom container controller.

将视图控制器与地图视图视为视图控制器A.将上滑/下移视图视为视图控制器B.我们希望从A无缝过渡到B(和B到A)。 Cocoa提供了一个用于执行此操作的API,但首先您需要一个包含A和B作为子视图控制器的容器视图控制器。这可以是导航控制器或您自己的自定义容器控制器。

Chapter 2: Noninteractive Custom Container View Controller Transition

Once you have the container view controller, code it up so that you can go from A to B and back by pressing a button. (Throw a debug button somewhere into your app.) So you tap a button and you go from A to B and then you tap it again to go from B to A. To do this, there are the noninteractive custom container view controller transition APIs (it's a mouthful). This will require implementing an animation controller and a transitioning delegate, as detailed in that excellent objc.io tutorial and its corresponding GitHub repository.

拥有容器视图控制器后,对其进行编码,以便按A按钮从A到B再返回。 (在你的应用程序的某个地方放一个调试按钮。)所以你点击一个按钮然后从A转到B然后再次点击它从B转到A.为此,有非交互式自定义容器视图控制器转换API (这是一口)。这将需要实现动画控制器和转换委托,详见优秀的objc.io教程及其相应的GitHub存储库。

Chapter 3: Interactive Custom Container View Controller Transition

But, of course, you want users to swipe up and down to trigger the transition. This will take you into the world of interactive blah blah blah APIs, where you implement an interaction controller and connect it to a pan gesture recognizer. The corresponding GitHub repository to that blog post actually uses a pan gesture like you would. This is particularly finicky work, as you would want the transition to be canceled should the user decide to stop panning midway through, but all that is detailed in the code and article.

但是,当然,您希望用户上下滑动以触发转换。这将带您进入交互式blah blah blah API的世界,您可以在其中实现交互控制器并将其连接到平移手势识别器。该博客文章的相应GitHub存储库实际上使用了像您一样的平移手势。这是特别挑剔的工作,因为如果用户决定在中途停止平移,您会希望取消转换,但所有这些都在代码和文章中详细说明。

Chapter 4: View Sharing

I'm actually not sure what this is called. The problem here is that you want the Google Maps / Spotify look and feel where a part of view controller B's view actually is visible while you're in view controller A. And the pan gesture recognizer is attached to B's view so that when you slide it up, B's view gets bigger and bigger until the interactive animation finishes and you've transitioned from A to B. Is there a good tutorial on this? I haven't found one, but it's becoming more and more common as an iOS UX idiom.

我其实不确定这叫什么。这里的问题是,当您在视图控制器A中时,您希望Google Maps / Spotify外观和视觉控制器B的视图的一部分实际可见。并且平移手势识别器附加到B的视图,以便在您滑动时B,视图越来越大,直到交互式动画结束,你已经从A转换为B.是否有一个很好的教程?我还没有找到一个,但它作为一个iOS用户界面的习惯用法变得越来越普遍。

I myself have a small demo project illustrating how to do this. What I do is I have a navigation controller as my container view controller. The navigation controller's root view controller is my home view controller (view controller A). In view controller, I have view controller B as a child. So that's navigation controller owns A owns B.

我自己有一个小型的演示项目,说明如何做到这一点。我所做的是我有一个导航控制器作为我的容器视图控制器。导航控制器的根视图控制器是我的主视图控制器(视图控制器A)。在视图控制器中,我将控制器B视为孩子。因此,导航控制器拥有A拥有B.

When the user taps on B, I push B onto the navigation stack, thus reparenting it. At that point, my noninteractive animation controller kicks in as a custom navigation controller push animation. And so it looks like B is smoothly transmogrifying from its small bounds to its larger bounds. (I recommend running the xcodeproj to see the effect as I have done a terrible job of describing it.)

当用户点击B时,我将B推到导航堆栈上,从而重新显示它。那时,我的非交互式动画控制器开始作为自定义导航控制器推送动画。因此看起来B很容易从它的小边界变形到更大的边界。 (我建议运行xcodeproj来查看效果,因为我已经做了很糟糕的描述。)

This technique would work just as well for an interactive animation. As to whether it's the best technique, I think that's up for debate — there are lots of ways of doing what you see in the Google Maps and Spotify apps. Apple could certainly do a lot better job of documenting the APIs for complex, interactive animations.

这种技术对于交互式动画也同样有效。至于它是否是最好的技术,我认为这是有争议的 - 有很多方法可以做你在Google Maps和Spotify应用程序中看到的内容。苹果当然可以更好地记录复杂的交互式动画的API。

I would caution you to avoid using Auto Layout until you have your animations tweaked and ready, as it doesn't really interact well with your animation controllers. Good ol' frame rectangle math is best here until you find your bearings. Auto Layout is magic and, as you might be able to tell from how exhaustingly long this answer is, there's already enough magic to go around.

我会提醒您在调整动画并准备好动画之前避免使用自动布局,因为它与动画控制器没有很好的交互作用。好的ol'框架矩形数学在这里是最好的,直到你找到你的轴承。自动布局是神奇的,正如你可能能够分辨出这个答案有多长,这已经足够神奇了。

See Also

You can click on the purple Apple logo in the top right of asciiwwdc.com pages to watch the videos of the talks or grab the PDFs from the Resources tabs. Some of the best documentation for iOS is locked up in these WWDC talks.

您可以单击asciiwwdc.com页面右上角的紫色Apple徽标,观看会谈的视频或从“资源”选项卡中获取PDF。 iOS的一些最佳文档被锁定在这些WWDC会谈中。