私のアプリのホームページには、UIButtons
、btnIncome
、およびbtnExpense
があります。このボタンを押すと、IncomeVC
とExpenseVC
がそれぞれプッシュされます。これらはxibを介してUIViewControllers
が追加された2つのUITabBar
です。 tabBarには4つのアイテムがあります。各タブ項目を選択すると、たとえばDailyVC、WeeklyVC、MonthlyVC、YearlyVCなど、UITableViews
およびIncomeVC
のサブビューと同じ4つのView Controller(ExpenseVC
を含む)が追加されます。 (すなわち、収入については、毎日、毎週などがあり、費用についても同じです)(IncomeVC
とExpenseVC
にはUIButton
とUIView
これはすべてのタブに共通です)。
問題は、btnIncome
をクリックすると、それらのテーブルビューに収入に関連する配列を追加する必要があり、その逆も同様です。どのviewControllerからさまざまなタブを選択したかを見つけるには(IncomeVCおよびExpenseVCのサブビューとして追加した4つのビューから取得する必要があります)。収入と費用についてそれぞれ8つの異なるビュー4を作成する必要がありますか?ありがとう.
前のView Controllerへのアクセスが必要な理由が取得するデータを知るためである場合、スタックにプッシュする前に新しいView Controllerにデータを提供することをお勧めします。または、View Controllerが適切なデータを取得する方法を知るのに十分なデータ、例えば列挙型または定数または何か。
これは、カスタム初期化子またはプロパティを使用して実行できます。例については、このブログ投稿をご覧ください。 "View Controller間でのデータの受け渡し"
ストーリーボードを使用している場合は、prepareForSegue:sender
正しいデータを渡します。それに関する良いチュートリアルはここにあります: iOS 5パート2のストーリーボードの開始
次のコードのように、以前のviewControllerを取得できます。
NSLog(@"%@",[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2]);
これにより、以前のviewController名が表示されます...
Swiftでは、
if let navController = self.navigationController, navController.viewControllers.count >= 2 {
let viewController = navController.viewControllers[navController.viewControllers.count - 2]
}
In Swift:
let n: Int! = self.navigationController?.viewControllers?.count
let myUIViewController = self.navigationController?.viewControllers[n-2] as! UIViewController
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がナビゲーションスタックの最上部にあるか、まったくないことを前提としています。
UIViewController *previousViewController = [[[self navigationController]viewControllers] objectAtIndex:([viewControllers indexOfObject:self]-1)];
Selfは現在のView Controllerです。
extension UINavigationController {
func getPreviousViewController() -> UIViewController? {
let count = viewControllers.count
guard count > 1 else { return nil }
return viewControllers[count - 2]
}
}
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)")
}
この投稿をチェックしてください: Navigation Stackで前のView Controllerを識別する方法 Tonyが正しい場合、前のVCをviewControllers配列から取得できますが、インデックスn-2 。
View Controllerを確実に再利用できます。ボタンが押されたときにUIViewController(IBから追加されたUITabBarを含む)をプッシュする代わりに、4つのView Controller(毎日、毎週、毎月、および毎年)を含むUITabBarControllerをプッシュすることをお勧めします。
UITabBarControllerには列挙プロパティ(IncomeおよびExpense)があり、押されたボタンに基づいてこのUITabBarControllerをプッシュするときに割り当てることができます。そこから、別の列挙型プロパティ(IncomeおよびExpense)を4つのUIViewControllersに割り当てて、各View Controllerで正しいタイプのデータを表示できます。