web-dev-qa-db-ja.com

現在のビューをプッシュした以前のViewControllerを取得する方法

私のアプリのホームページには、UIButtonsbtnIncome、およびbtnExpenseがあります。このボタンを押すと、IncomeVCExpenseVCがそれぞれプッシュされます。これらはxibを介してUIViewControllersが追加された2つのUITabBarです。 tabBarには4つのアイテムがあります。各タブ項目を選択すると、たとえばDailyVC、WeeklyVC、MonthlyVC、YearlyVCなど、UITableViewsおよびIncomeVCのサブビューと同じ4つのView Controller(ExpenseVCを含む)が追加されます。 (すなわち、収入については、毎日、毎週などがあり、費用についても同じです)(IncomeVCExpenseVCにはUIButtonUIViewこれはすべてのタブに共通です)。

問題は、btnIncomeをクリックすると、それらのテーブルビューに収入に関連する配列を追加する必要があり、その逆も同様です。どのviewControllerからさまざまなタブを選択したかを見つけるには(IncomeVCおよびExpenseVCのサブビューとして追加した4つのビューから取得する必要があります)。収入と費用についてそれぞれ8つの異なるビュー4を作成する必要がありますか?ありがとう.

35
Midas

前のView Controllerへのアクセスが必要な理由が取得するデータを知るためである場合、スタックにプッシュする前に新しいView Controllerにデータを提供することをお勧めします。または、View Controllerが適切なデータを取得する方法を知るのに十分なデータ、例えば列挙型または定数または何か。

これは、カスタム初期化子またはプロパティを使用して実行できます。例については、このブログ投稿をご覧ください。 "View Controller間でのデータの受け渡し"

ストーリーボードを使用している場合は、prepareForSegue:sender正しいデータを渡します。それに関する良いチュートリアルはここにあります: iOS 5パート2のストーリーボードの開始

9
Vegar

次のコードのように、以前のviewControllerを取得できます。

NSLog(@"%@",[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2]);

これにより、以前のviewController名が表示されます...

35
Venk

Swiftでは、

if let navController = self.navigationController, navController.viewControllers.count >= 2 {
     let viewController = navController.viewControllers[navController.viewControllers.count - 2]
}
31
Venk

In Swift

let n: Int! = self.navigationController?.viewControllers?.count
let myUIViewController = self.navigationController?.viewControllers[n-2] as! UIViewController
20
King-Wizard

Swift

以下は、拡張機能に含めることができる以前の回答のマッシュアップです。

extension UIViewController{
   var previousViewController:UIViewController?{
        if let controllersOnNavStack = self.navigationController?.viewControllers, controllersOnNavStack.count >= 2 {
            let n = controllersOnNavStack.count
            return controllersOnNavStack[n - 2]
        }
        return nil
    }
}

編集:

特定のView ControllerのpreviousViewControllerをフェッチする場合、VC1をviewWillDisappearで呼び出します。VC1はすでにNavigation Controller Stackからポップされています。したがって、このシナリオでは、上記のコードはVC1のすぐ上のView Controller(VC2と呼びます)ではなく、VC2の上のView Controller(存在する場合)を取得します。

この問題を回避するには、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メッセージを送信するView Controllerがナビゲーションスタックの最上部にあるか、まったくないことを前提としています。

9
J.beenie
UIViewController *previousViewController = [[[self navigationController]viewControllers] objectAtIndex:([viewControllers indexOfObject:self]-1)];

Selfは現在のView Controllerです。

4
Zaraki

Swift

extension UINavigationController {
    func getPreviousViewController() -> UIViewController? {
        let count = viewControllers.count
        guard count > 1 else { return nil }
        return viewControllers[count - 2]
    }
}
2
dimpiax

Swift 4.1、4.2

 let allPreviousViewC = currentViewController.navigationController?.viewControllers // will give array of all pushed VC
// Can use if condition to check array count and then put below code inside that condition
    for viewC in allPreviousViewC! {
           print("ViewC is \(viewC)")
      }
1
GSK

この投稿をチェックしてください: Navigation Stackで前のView Controllerを識別する方法 Tonyが正しい場合、前のVCをviewControllers配列から取得できますが、インデックスn-2 。

0
CharlieReed

View Controllerを確実に再利用できます。ボタンが押されたときにUIViewController(IBから追加されたUITabBarを含む)をプッシュする代わりに、4つのView Controller(毎日、毎週、毎月、および毎年)を含むUITabBarControllerをプッシュすることをお勧めします。

UITabBarControllerには列挙プロパティ(IncomeおよびExpense)があり、押されたボタンに基づいてこのUITabBarControllerをプッシュするときに割り当てることができます。そこから、別の列挙型プロパティ(IncomeおよびExpense)を4つのUIViewControllersに割り当てて、各View Controllerで正しいタイプのデータを表示できます。

0
Valent Richie