我的应用的主页有UIButtons
,btnIncome
和btnExpense
。按此按钮可以分别推送IncomeVC
和ExpenseVC
,这两个UIViewControllers
通过xib添加了UITabBar
。 tabBar有4个项目。在每个标签项上选择添加相同的四个视图控制器(其中包含UITableViews
)作为IncomeVC
和ExpenseVC
的子视图,例如,DailyVC,WeeklyVC,MonthlyVC,YearlyVC。(即,对于收入,每日,每周等都有相同的费用)(我这样做是因为IncomeVC
和ExpenseVC
有UIButton
和UIView
这是常见的对于所有标签)。
所以问题是,如果点击btnIncome
,我必须使用与收入相关的数组填充这些表视图,反之亦然。如何从哪个viewController中找到我选择的不同选项卡(我需要从我添加的4个视图中获取它作为IncomeVC和ExpenseVC的子视图)。我是否必须为收入和费用制作8个不同的视图4?
感谢名单。
答案 0 :(得分:34)
您可以像以下代码一样获取之前的viewController,
NSLog(@"%@",[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2]);
这将显示上一个viewController名称...
答案 1 :(得分:28)
在 Swift 3 中,
func parseJson(_ JsonDict: AnyObject)
{
var data = [newsarticle]()
if let nameDic = JsonDict!["result"]["ReturnValue"]["tree"]["children"] as? [AnyObject] {
for dict2 in nameDic {
data.append(newsarticle(name: (dict2 as? [String : AnyObject])?["text"],desc: "https://www.oncoursesystems.com/school/webpage/\((dict2 as? [String : AnyObject])?["id"])/689493"))
}
}
addData(data)
}
答案 2 :(得分:20)
在 Swift :
let n: Int! = self.navigationController?.viewControllers?.count
let myUIViewController = self.navigationController?.viewControllers[n-2] as! UIViewController
答案 3 :(得分:9)
Swift 3
以下是可以放入扩展程序的先前答案的混搭:
extension UIViewController{
var previousViewController:UIViewController?{
if let controllersOnNavStack = self.navigationController?.viewControllers, controllersOnNavStack.count >= 2 {
let n = controllersOnNavStack.count
return controllersOnNavStack[n - 2]
}
return nil
}
}
修改强>
当获取给定视图控制器的previousViewController
时,将其称为VC1,在viewWillDisappear
中,VC1已经弹出导航控制器堆栈。因此,在这种情况下,上面的代码最终不会直接在VC1上方(称为VC2)获取View控制器,而是在VC2上方(如果存在)获取视图控制器。
为了避免这个问题,我只是在请求previousViewController
时检查VC1是否仍在堆栈中。这是更新的代码:
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
}
}
此代码假定您发送previousViewController
消息的视图控制器将位于导航堆栈的顶部或根本不存在。
答案 4 :(得分:7)
如果需要访问前一个视图控制器的原因是要知道要获取哪些数据,我建议您在将新数据推送到堆栈之前为新视图控制器提供数据。或至少足够的数据,以便视图控制器知道如何获得正确的数据,例如枚举或常数或其他东西。
这可以使用自定义初始化程序或属性来完成。 请查看此博客文章中的示例:"Passing Data Between View Controllers"
如果您使用的是故事板,则可以使用prepareForSegue:sender
传递正确的数据。有关它的详细教程可以在这里找到:Beginning Storyboards in iOS 5 Part 2
答案 5 :(得分:4)
UIViewController *previousViewController = [[[self navigationController]viewControllers] objectAtIndex:([viewControllers indexOfObject:self]-1)];
self将成为当前视图控制器。
答案 6 :(得分:1)
extension UINavigationController {
func getPreviousViewController() -> UIViewController? {
let count = viewControllers.count
guard count > 1 else { return nil }
return viewControllers[count - 2]
}
}
答案 7 :(得分:1)
(基于先前的答案,但更简单)
extension UINavigationController {
var previousViewController: UIViewController? {
return viewControllers.count > 1 ? viewControllers[viewControllers.count - 2] : nil
}
}
答案 8 :(得分:0)
您当然可以重用视图控制器。当按下按钮时,我建议不要按UIViewController(包含从IB添加的UITabBar),你可以推送包含4个View Controllers的UITabBarController(每日,每周,每月和每年)。
你UITabBarController可以有一个枚举属性(收入和费用),这可以在你按下按钮按下这个UITabBarController时分配。从那里,您可以为4个UIViewControllers分配另一个枚举属性(收入和费用),以在每个视图控制器中显示正确的数据类型。
答案 9 :(得分:0)
查看此信息:How to identify previous view controller in navigation stack Tony是对的,您可以从viewControllers数组中获取前一个VC,但索引为n-2。
答案 10 :(得分:0)
此处的所有答案都实现了 [viewControllers.count - 2]
方法,但它返回最后一个视图控制器的前一个控制器,未说明!如果说明的视图控制器不是 导航堆栈的最后一个视图控制器,[viewControllers.count - 2]
返回不正确的结果。
新解决方案:
extension UIViewController {
var previousViewController: UIViewController? {
guard let viewControllers = navigationController?.viewControllers,
let index = viewControllers.index(of: self),
index > 0
else { return nil }
return viewControllers[index - 1]
}
}