可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have 2 seperate navigationcontrollers
, one with RootViewController
A and the other with RootViewController
B.
I am able to push ViewController
C onto either A or B's navigation stack.
Question: When I am in ViewController
C, how can I find out if I am in the stack belonging to A or B?
回答1:
You could use the UINavigationController
's viewControllers
property:
@property(nonatomic, copy) NSArray *viewControllers
Discussion: The root view controller is at index 0 in the array, the back view controller is at index n-2, and the top controller is at index n-1, where n is the number of items in the array.
https://developer.apple.com/documentation/uikit/uinavigationcontroller
You could use that to test whether the root view controller (the one at array index 0) is view controller A or B.
回答2:
Here's the implementation of the accepted answer:
- (UIViewController *)backViewController
{
NSInteger numberOfViewControllers = self.navigationController.viewControllers.count;
if (numberOfViewControllers < 2)
return nil;
else
return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2];
}
回答3:
- (UIViewController *)backViewController
{
NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];
if ( myIndex != 0 && myIndex != NSNotFound ) {
return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
} else {
return nil;
}
}
回答4:
A more general implementation of the accepted answer:
- (UIViewController *)backViewController {
NSArray * stack = self.navigationController.viewControllers;
for (int i=stack.count-1; i > 0; --i)
if (stack[i] == self)
return stack[i-1];
return nil;
}
This will return the correct "back view controller" regardless of where the current class is on the navigation stack.
回答5:
Swift implementation of tjklemz code as an extension:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for(var i=stack.count-1;i>0;--i) {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
回答6:
Here's a modifed version of Prabhu Beeman's Swift code that adapts it to support Swift 3:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for i in (1..<stack.count).reverse() {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
回答7:
Access the n-2
element of the viewControllers
property to access the parent view controller.
Once you have that instance, you can check its type by logging what comes out of the NSStringFromClass()
function. Or you could keep some static const
identifier string in controllers A and B, and a getter function that prints out the string.
回答8:
As a UINavigationController
extension:
extension UINavigationController {
func previousViewController() -> UIViewController? {
guard viewControllers.count > 1 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
回答9:
Swift implementation of @tjklemz code:
var backViewController : UIViewController? {
var stack = self.navigationController!.viewControllers as Array
for (var i = stack.count-1 ; i > 0; --i) {
if (stack[i] as UIViewController == self) {
return stack[i-1] as? UIViewController
}
}
return nil
}
回答10:
Use the navigationController
method to retrieve it. See documentation on Apple's site.
navigationController A parent or ancestor that is a navigation
controller. (read-only)
@property(nonatomic, readonly, retain) UINavigationController
*navigationController
Discussion Only returns a navigation controller if the view
controller is in its stack. This property is nil if a navigation
controller cannot be found.
Availability Available in iOS 2.0 and later.
回答11:
Because dead horses enjoy being beaten :)
- (UIViewController *)previousViewController
{
NSArray *vcStack = self.navigationController.viewControllers;
NSInteger selfIdx = [vcStack indexOfObject:self];
if (vcStack.count < 2 || selfIdx == NSNotFound) { return nil; }
return (UIViewController *)[vcStack objectAtIndex:selfIdx - 1];
}
回答12:
Find the previous view controller is simple.
In your case, i.e., you are in C and you need B, [self.navigationController.viewControllers lastObject]
is what you want.
For A, since A is the root view controller, you can just replace lastObject
with firstObject
to obtain.
回答13:
Implementation for Swift 2.2 - Add this in an UIViewController
extension. Safe in the sense it will return nil
if the viewcontroller is the rootvc or not in a navigationcontroller.
var previousViewController: UIViewController? {
guard let viewControllers = navigationController?.viewControllers else {
return nil
}
var previous: UIViewController?
for vc in viewControllers{
if vc == self {
break
}
previous = vc
}
return previous
}
回答14:
With Swift using guard.
extension UIViewController {
func getPreviousViewController() -> UIViewController? {
guard let _ = self.navigationController else {
return nil
}
guard let viewControllers = self.navigationController?.viewControllers else {
return nil
}
guard viewControllers.count >= 2 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
回答15:
My extension, swift 3
extension UIViewController {
var previousViewController: UIViewController? {
guard let controllers = navigationController?.viewControllers, controllers.count > 1 else { return nil }
switch controllers.count {
case 2: return controllers.first
default: return controllers.dropLast(2).first
}
}
}
回答16:
for swift 3 you can do this:
var backtoViewController:UIViewController!
for viewController in (self.navigationController?.viewControllers)!.reversed() {
if viewController is NameOfMyDestinationViewController {
backtoViewController = viewController
}
}
self.navigationController!.popToViewController(backtoViewController, animated: true)
You only need replace "NameOfMyDestinationViewController" by viewController that you want to return.
回答17:
A more succinct Swift impementation:
extension UIViewController {
var previousViewController: UIViewController? {
guard let nav = self.navigationController,
let myIdx = nav.viewControllers.index(of: self) else {
return nil
}
return myIdx == 0 ? nil : nav.viewControllers[myIdx-1]
}
}