可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The home page of my app has UIButtons
, btnIncome
and btnExpense
. Pressing on this buttons pushes IncomeVC
and ExpenseVC
respectevely,which are two UIViewControllers
with UITabBar
added via xib. The tabBar have 4 items. Selecting on each tab item adds same four view controllers(which contains UITableViews
) as the subview of IncomeVC
and ExpenseVC
,like for eg, DailyVC,WeeklyVC,MonthlyVC,YearlyVC.(ie,for Income ,there is daily,weekly etc and same for Expense) (I have done like that because the IncomeVC
and ExpenseVC
have a UIButton
and a UIView
which is common for all tabs).
So the problem is that, if click the btnIncome
I have to populate those tableviews with the arrays related to Income and vice versa for Expense. How can I find from which viewController I selected the different tabs(I need to get it from the 4 Views I added as the subview of IncomeVC and ExpenseVC). Do I have to make 8 different views 4 each for Income and expense ?
Thanx.
回答1:
If the reason for needing access to the previous view controller is to know what data to get, I would suggest that you instead give the new view controller the data before you push it on the stack. Or at least enough data so that the view controller know how to get the right data, e.g. a enum or constant or something.
This could be done with a custom initializer, or a property.
Take a look at this blog post for an example: "Passing Data Between View Controllers"
If you are using a storyboard, you can use prepareForSegue:sender
to pass the right data. A good tutorial on that can be found here: Beginning Storyboards in iOS 5 Part 2
回答2:
You can get the previous viewController like following code,
NSLog(@"%@",[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2]);
This will displays the previous viewController name...
回答3:
In Swift 3,
if let navController = self.navigationController, navController.viewControllers.count >= 2 {
let viewController = navController.viewControllers[navController.viewControllers.count - 2]
}
回答4:
In Swift:
let n: Int! = self.navigationController?.viewControllers?.count
let myUIViewController = self.navigationController?.viewControllers[n-2] as! UIViewController
回答5:
Swift 3
Here is a mashup of the previous answers that can be put into an extension:
extension UIViewController{
var previousViewController:UIViewController?{
if let controllersOnNavStack = self.navigationController?.viewControllers, controllersOnNavStack.count >= 2 {
let n = controllersOnNavStack.count
return controllersOnNavStack[n - 2]
}
return nil
}
}
Edit:
When fetching the previousViewController
of a given view controller, call it VC1, in viewWillDisappear
, VC1 is already popped of the Navigation Controller Stack. So in this scenario, the above code does not end up fetching the View controller directly above VC1(call it VC2), but the view controller above VC2 (if it exists).
To avoid this problem I just check if VC1 is still on the stack when previousViewController
is requested. Here is the updated code:
extension UIViewController{
var previousViewController:UIViewController?{
if let controllersOnNavStack = self.navigationController?.viewControllers{
let n = controllersOnNavStack.count
//if self is still on Navigation stack
if controllersOnNavStack.last === self, n > 1{
return controllersOnNavStack[n - 2]
}else if n > 0{
return controllersOnNavStack[n - 1]
}
}
return nil
}
}
This code assumes that view controller you are sending the previousViewController
message to will either be at the top of the navigation stack or not at all.
回答6:
UIViewController *previousViewController = [[[self navigationController]viewControllers] objectAtIndex:([viewControllers indexOfObject:self]-1)];
Where self will be current view controller.
回答7:
Swift
extension UINavigationController {
func getPreviousViewController() -> UIViewController? {
let count = viewControllers.count
guard count > 1 else { return nil }
return viewControllers[count - 2]
}
}
回答8:
You can certainly reuse the view controllers. I would suggest instead of pushing UIViewController (which contains UITabBar added from IB) when the button is pressed, you can push UITabBarController which contains 4 View Controllers (daily, weekly, monthly, and yearly).
You UITabBarController could have an enum property (Income and Expense) and this can be assigned when you push this UITabBarController based on the button pressed. From there, you can assign another enum property (Income and Expense) to the 4 UIViewControllers to show the correct type of data in each view controller.
回答9:
Check out this post: How to identify previous view controller in navigation stack
Tony is right, you can get the previous VC from the viewControllers array but at index n-2.
回答10:
Swift 4.1, 4.2
let allPreviousViewC = currentViewController.navigationController?.viewControllers // will give array of all pushed VC
for viewC in allPreviousViewC! {
print("ViewC is \(viewC)")
}