问题
I am using navigation based application. I push First ViewController to Second ViewController and from Second ViewController to Third ViewController. Now I want to pop from Third ViewController to First ViewController.I am performing this task using the below code but my application crashed.
Please any body give me some proper guidelines. I can't use pop to rootViewController because it's different viewController. Thanks in advance...
In Third ViewControler i have written this:
FirstViewCtr *x=[[FirstViewCtr alloc] initWithNibName:@"FirstViewCtr" bundle:nil];
[self.navigationController popToViewController:x animated:NO];
回答1:
By Writing the First Line you get the Indexes of all View Controllers and from second Line You will reach up to your Destination.
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];
回答2:
A safer approach:
- (void)turnBackToAnOldViewController{
for (UIViewController *controller in self.navigationController.viewControllers) {
//Do not forget to import AnOldViewController.h
if ([controller isKindOfClass:[AnOldViewController class]]) {
[self.navigationController popToViewController:controller
animated:YES];
return;
}
}
}
回答3:
Swifty way:
let dashboardVC = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
navigationController!.popToViewController(dashboardVC, animated: true)
回答4:
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
回答5:
Often it is more important to do that from top of stack, so:
- (void)popToLast:(Class)aClass
{
for (int i=self.navigationController.viewControllers.count-1; i>=0; i--)
{
UIViewController *vc = self.navigationController.viewControllers[i];
if ([vc isKindOfClass:aClass])
{
[self.navigationController popToViewController:vc animated:YES];
break;
}
}
}
and you call that
popToLast:[SomeViewController class];
回答6:
- (void) RetunToSpecificViewController{
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[AnOldViewController class]])
{
//Do not forget to import AnOldViewController.h
[self.navigationController popToViewController:controller
animated:YES];
break;
}
}
}
回答7:
Swift 4 version
if let viewController = navigationController?.viewControllers.first(where: {$0 is YourViewController}) {
navigationController?.popToViewController(viewController, animated: false)
}
You may specify another filter on .viewControllers.first
as per your need e.g lets say if you have same kind
of view controllers residing in the navigation controller then you may specify an additional check like below
if let viewController = navigationController?.viewControllers.first(where: {
if let current = $0 as? YourViewController {
return current.someProperty == "SOME VALUE"
}
return false } ) {
navigationController?.popToViewController(viewController, animated: false)
}
回答8:
Quick and safe Swift 3 version:
if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
navigationController.popToViewController(vc, animated: true)
}
回答9:
Your code creates a new instance of a view that has never been pushed onto the stack, then tries to pop back to that controller.
If you are popping back to the root view controller, you can uses popToRootViewControllerAnimated:
If you are popping back a known distance you can call popViewControllerAnimated:
more than once. In your example, that would be 2 controllers so to calls. You could do the same thing by looking in viewControllers
for the controller 2 from the end and popping to it.
The above suggestions are quick fixes. One best practice scenario would be to pass the controller you want to return to along to each successive controller you push. First passes itself to second, second passes that reference to third, third pops to the passed reference, which is first.
In effect, you are creating a temporary root controller. You could subclass UINavigationController
and add a temporaryRoot
property and a popToTemporaryRootViewControllerAnimated:
method that would pop to your temporary root and clear it. When first pushes seconds, it would also set itself as the temporary root so that every controller in the stack does not have to pass a reference around. You would have to add some extra checks to unsure you never pop past the temporaryRoot without clearing it.
回答10:
After lots of effort someone has created swift extension of back to a particular view controller in Swift 3.0.
extension UINavigationController {
func backToViewController(viewController: Swift.AnyClass) {
for element in viewControllers as Array {
if element.isKind(of: viewController) {
self.popToViewController(element, animated: true)
break
}
}
}
}
Method calling:
self.navigationController?.backToViewController(viewController: YourViewController.self)
回答11:
Implemented & Tested in Swift 3.0
Below is Method which can useful for Navigate to any specific View Controller :
func poptoSpecificVC(viewController : Swift.AnyClass){
let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for aViewController in viewControllers {
if aViewController.isKind(of: viewController) {
self.navigationController!.popToViewController(aViewController, animated: true)
break;
}
}
}
Usage :
self.poptoSpecificVC(viewController: createIntervalVC.self)
回答12:
I think that .filter({...}).first
is a little bit slower than .first(where: {...})
.
Also this could be written more precisely to address only UIViewControllers.
extension UINavigationController {
func popToController<T: UIViewController>(_ type: T.Type, animated: Bool) {
if let vc = viewControllers.first(where: { $0 is T }) {
popToViewController(vc, animated: animated)
}
}
func popToControllerOrToRootControllerIfNotInTheStack<T: UIViewController>(_ type: T.Type, animated: Bool) {
if let vc = viewControllers.first(where: { $0 is T }) {
popToViewController(vc, animated: animated)
} else {
popToRootViewController(animated: animated)
}
}
}
回答13:
Updated for Swift 3:
used below simple code, for pop to specific view controller;
for vc in self.navigationController!.viewControllers as Array {
if vc.isKind(of: YourViewControllerName) {
self.navigationController!.popToViewController(vc, animated: true)
break
}
}
回答14:
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: LoginVC.self) {
_ = self.navigationController!.popToViewController(controller, animated: true)
break
}
}
回答15:
Put function in UIViewController
1. it checks if Specific UIViewController
exists In UINavigationController
then popToViewController
or else pushViewController
func navigate(_ navVC: AnyClass, pushVC: UIViewController) {
for obj in self.navigationController!.viewControllers {
if obj.isMember(of: navVC) {
self.navigationController!.popToViewController(obj, animated: true)
return
}
}
self.navigationController!.pushViewController(pushVC, animated: true)
}
Use
self.navigate(ViewController.self, pushVC: self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController)
回答16:
i have answer here. This is 100% working code for Swift > 4.X
How can I pop specific View Controller in Swift
来源:https://stackoverflow.com/questions/3027559/can-i-pop-to-specific-viewcontroller