如何获取推送当前视图的上一个viewcontroller

时间:2013-05-17 12:03:07

标签: iphone uiviewcontroller uinavigationcontroller uitabbarcontroller

我的应用的主页有UIButtonsbtnIncomebtnExpense。按此按钮可以分别推送IncomeVCExpenseVC,这两个UIViewControllers通过xib添加了UITabBar。 tabBar有4个项目。在每个标签项上选择添加相同的四个视图控制器(其中包含UITableViews)作为IncomeVCExpenseVC的子视图,例如,DailyVC,WeeklyVC,MonthlyVC,YearlyVC。(即,对于收入,每日,每周等都有相同的费用)(我这样做是因为IncomeVCExpenseVCUIButtonUIView这是常见的对于所有标签)。

所以问题是,如果点击btnIncome,我必须使用与收入相关的数组填充这些表视图,反之亦然。如何从哪个viewController中找到我选择的不同选项卡(我需要从我添加的4个视图中获取它作为IncomeVC和ExpenseVC的子视图)。我是否必须为收入和费用制作8个不同的视图4? 感谢名单。

11 个答案:

答案 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)

Swift 5.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]
    }
}