ios 关闭呈现的视图控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14636891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dismissing a Presented View Controller
提问by nikitahils
I have a theoretic question. Now ?'m reading Apple's ViewControllerguide.
我有一个理论问题。现在?正在阅读 Apple 的ViewController指南。
They wrote:
他们写:
When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it. Although there are several techniques for notifying the presenting view controller that its presented view controller should be dismissed, the preferred technique is delegation.
当需要关闭呈现的视图控制器时,首选方法是让呈现的视图控制器关闭它。换句话说,只要有可能,呈现视图控制器的同一个视图控制器也应该负责解除它。尽管有多种技术可以通知呈现视图控制器其呈现的视图控制器应该被解除,但首选技术是委托。
But I can't explain, why I have to create a protocol in presented VC and add delegate varible, create delegate method in presenting VC for dismissing presented VC, instead of a simple call in presentedview controller method
但我无法解释,为什么我必须在呈现的 VC 中创建一个协议并添加委托变量,在呈现 VC 中创建委托方法以消除呈现的 VC,而不是在呈现的视图控制器方法中进行简单调用
[self dismissViewControllerAnimated:NO completion:nil]
?
[self dismissViewControllerAnimated:NO completion:nil]
?
Why is the first choice better? Why does Apple recommend it?
为什么第一选择更好?为什么苹果推荐它?
回答by foundry
I think Apple are covering their backs a little here for a potentially kludgy piece of API.
我认为 Apple 正在为一个潜在的笨拙的 API 提供一些支持。
[self dismissViewControllerAnimated:NO completion:nil]
Is actually a bit of a fiddle. Although you can - legitimately - call this on the presented view controller, all it does is forward the message on to the presenting view controller. If you want to do anything over and above just dismissing the VC, you will need to know this, and you need to treat it much the same way as a delegate method - as that's pretty much what it is, a baked-in somewhat inflexible delegate method.
其实有点扯。尽管您可以 - 合法地 - 在呈现的视图控制器上调用它,但它所做的只是将消息转发到呈现的视图控制器。如果你想在解雇 VC 之外做任何事情,你需要知道这一点,你需要像对待委托方法一样对待它 - 因为它几乎就是这样,一个有点不灵活的烘焙委托方法。
Perhaps they've come across loads of bad code by people not really understanding how this is put together, hence their caution.
也许他们遇到了很多糟糕的代码,人们并不真正理解这是如何组合在一起的,因此他们很谨慎。
But of course, if all you need to do is dismiss the thing, go ahead.
但是,当然,如果您需要做的只是忽略这件事,请继续。
My own approach is a compromise, at least it reminds me what is going on:
我自己的做法是一种妥协,至少它提醒了我是怎么回事:
[[self presentingViewController] dismissViewControllerAnimated:NO completion:nil]
[Swift]
[迅速]
self.presentingViewController?.dismiss(animated: false, completion:nil)
回答by Suragch
Updated for Swift 3
为 Swift 3 更新
I came here just wanting to dismiss the current (presented) View Controller. I'm making this answer for anyone coming here with the same purpose.
我来到这里只是想关闭当前(呈现的)视图控制器。我正在为出于相同目的来到这里的任何人做出这个答案。
Navigation Controller
导航控制器
If you are using a navigation controller, then it is quite easy.
如果您使用的是导航控制器,那么这很容易。
Go back to the previous view controller:
回到之前的视图控制器:
// Swift
self.navigationController?.popViewController(animated: true)
// Objective-C
[self.navigationController popViewControllerAnimated:YES];
Go back to the root view controller:
回到根视图控制器:
// Swift
self.navigationController?.popToRootViewController(animated: true)
// Objective-C
[self.navigationController popToRootViewControllerAnimated:YES];
(Thanks to this answerfor the Objective-C.)
Modal View Controller
模态视图控制器
When a View Controller is presented modally, you can dismiss it (from the second view controller) by calling
当视图控制器以模态呈现时,您可以通过调用(从第二个视图控制器)关闭它
// Swift
self.dismiss(animated: true, completion: nil)
// Objective-C
[self dismissViewControllerAnimated:YES completion:nil];
The documentationsays,
该文件说,
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.
呈现视图控制器负责解除它呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,UIKit 会要求呈现的视图控制器处理关闭。
So it works for the presented view controller to call it on itself. Hereis a full example.
所以它适用于呈现的视图控制器来调用它自己。这是一个完整的例子。
Delegates
代表
The OP's question was about the complexity of using delegates to dismiss a view.
OP 的问题是关于使用代表驳回观点的复杂性。
- This Objective-C answergoes into it quite a bit.
- Hereis a Swift example.
- 这个 Objective-C 的答案涉及很多。
- 这是一个 Swift 示例。
To this point I have not needed to use delegates since I usually have a navigation controller or modal view controllers, but if I do need to use the delegate patternin the future, I will add an update.
到目前为止,我不需要使用委托,因为我通常有一个导航控制器或模式视图控制器,但是如果我将来确实需要使用委托模式,我会添加一个更新。
回答by Michael Enriquez
This is for view controller reusability.
这是为了视图控制器的可重用性。
Your view controller shouldn't care if it is being presented as a modal, pushed on a navigation controller, or whatever. If your view controller dismisses itself, then you're assuming it is being presented modally. You won't be able to push that view controller onto a navigation controller.
您的视图控制器不应该关心它是作为模态呈现、推送到导航控制器上还是其他任何东西。如果您的视图控制器自行关闭,那么您假设它是以模态呈现的。您将无法将该视图控制器推送到导航控制器上。
By implementing a protocol, you let the parent view controller decide how it should be presented/pushed and dismissed/popped.
通过实现一个协议,你让父视图控制器决定它应该如何呈现/推送和解除/弹出。
回答by Oshitha Wimalasuriya
try this:
尝试这个:
[self dismissViewControllerAnimated:true completion:nil];
回答by jhilgert00
In my experience, it comes in handy when you need to dismiss it from anyViewController you want and perform different tasks for each viewcontroller that dismisses it. Any viewController that adopts the protocol can dismiss the view in it's own way. (ipad vs iphone, or passing different data when dismissing from different views, calling different methods when dismissing, etc..)
根据我的经验,当您需要从任何您想要的 ViewController 中关闭它并为每个关闭它的ViewController 执行不同的任务时,它会派上用场。任何采用该协议的 viewController 都可以以自己的方式关闭视图。(ipad vs iphone,或者从不同的视图关闭时传递不同的数据,关闭时调用不同的方法等。)
Edit:
编辑:
So, to clarify, if all you ever want to do is dismiss the view, I see no need to setup the delegate protocol. If you need to do different things afteryou dismiss it from different presenting view controllers, It would be your best way to go using the delegate.
因此,澄清一下,如果您只想关闭视图,我认为没有必要设置委托协议。如果在从不同的呈现视图控制器中关闭它后需要做不同的事情,这将是使用委托的最佳方式。
回答by Pranit
Swift 3.0//Dismiss View Controller in swift
Swift 3.0//快速关闭视图控制器
self.navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)
回答by svena
Quote from View Controller Programming Guide, "How View Controllers Present Other View Controllers".
引用自视图控制器编程指南,“视图控制器如何呈现其他视图控制器”。
Each view controller in a chain of presented view controllers has pointers to the other objects surrounding it in the chain. In other words, a presented view controller that presents another view controller has valid objects in both its presentingViewController and presentedViewController properties. You can use these relationships to trace through the chain of view controllers as needed. For example, if the user cancels the current operation, you can remove all objects in the chain by dismissing the first presented view controller. Dismissing a view controller dismisses not only that view controller but also any view controllers it presented.
呈现的视图控制器链中的每个视图控制器都有指向链中围绕它的其他对象的指针。换句话说,呈现另一个视图控制器的呈现视图控制器在其presentingViewController 和presentedViewController 属性中都具有有效对象。您可以根据需要使用这些关系来跟踪视图控制器链。例如,如果用户取消当前操作,您可以通过关闭第一个呈现的视图控制器来删除链中的所有对象。关闭视图控制器不仅会关闭该视图控制器,还会关闭它呈现的任何视图控制器。
So on one hand it makes for a nice balanced design, good de-coupling, etc... But on the other hand it's very practical, because you can quickly get back to a certain point in navigation.
因此,一方面它可以实现良好的平衡设计、良好的解耦等……但另一方面它非常实用,因为您可以快速返回导航中的某个点。
Although, I personally would rather use unwinding seguesthan try to traverse backwards the presenting view controllerstree, which is what Apple talks about in this chapter where the quote is from.
尽管如此,我个人更愿意使用展开segues而不是尝试向后遍历呈现的视图控制器树,这是Apple在本章中谈到的引用来源。
回答by Abdurrahman Mubeen Ali
One point is that this is a good coding approach. It satisfies many OOP
principles, eg., SRP, Separation of concerns etc.
有一点是,这是一种很好的编码方法。它满足许多OOP
原则,例如,SRP、关注点分离等。
So, the view controller presenting the view should be the one dismissing it.
因此,呈现视图的视图控制器应该是关闭它的那个。
Like, a real estate company who gives a house on rent should be the authority to take it back.
比如,一家提供出租房屋的房地产公司应该有权收回它。
回答by Mayur
In addition to Michael Enriquez's answer, I can think of one other reason why this may be a good way to protect yourself from an undetermined state:
除了 Michael Enriquez 的回答,我还能想到另一个原因,为什么这可能是保护自己免受不确定状态的好方法:
Say ViewControllerA presents ViewControllerB modally. But, since you may not have written the code for ViewControllerA you aren't aware of the lifecycle of ViewControllerA. It may dismiss 5 seconds (say) after presenting your view controller, ViewControllerB.
假设 ViewControllerA 以模态方式呈现 ViewControllerB。但是,由于您可能没有为 ViewControllerA 编写代码,因此您不了解 ViewControllerA 的生命周期。在呈现您的视图控制器 ViewControllerB 后,它可能会关闭 5 秒(比如说)。
In this case, if you were simply using dismissViewController
from ViewControllerB to dismiss itself, you would end up in an undefined state--perhaps not a crash or a black screen but an undefined state from your point of view.
在这种情况下,如果您只是使用dismissViewController
from ViewControllerB 来关闭自身,您最终会处于未定义状态——从您的角度来看,可能不是崩溃或黑屏,而是未定义状态。
If, instead, you were using the delegate pattern, you would be aware of the state of ViewControllerB and you can program for a case like the one I described.
相反,如果您使用的是委托模式,您将了解 ViewControllerB 的状态,并且您可以针对我描述的情况进行编程。
回答by Rishi Chaurasia
Swift
迅速
let rootViewController:UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!
if (rootViewController.presentedViewController != nil) {
rootViewController.dismiss(animated: true, completion: {
//completion block.
})
}