Подтвердить что ты не робот

Как получить предыдущий viewcontroller, который подтолкнул мое текущее представление

Домашняя страница моего приложения имеет UIButtons, btnIncome и btnExpense. Нажатие на эти кнопки значительно увеличивает IncomeVC и ExpenseVC, которые являются двумя UIViewControllers с UITabBar, добавленными через xib. TabBar имеет 4 элемента. При выборе в каждом элементе табуляции добавляются те же четыре контроллера представлений (которые содержат UITableViews) в качестве поднабора IncomeVC и ExpenseVC, например, DailyVC, WeeklyVC, MonthlyVC, YearlyVC. (Т. Е. Для Дохода, ежедневно, еженедельно и т.д. и так же для Expense) (я сделал это так, потому что IncomeVC и ExpenseVC имеют UIButton и UIView, которые являются общими для всех вкладок).

Итак, проблема в том, что если щелкнуть по btnIncome, мне нужно заполнить эти таблицы с помощью массивов, связанных с Доходом и наоборот для Expense. Как я могу найти, с какого viewController я выбрал разные вкладки (мне нужно получить его из 4 представлений, которые я добавил в качестве подзаголовка IncomeVC и ExpenseVC). Должен ли я каждый день составлять 8 разных просмотров для дохода и расходов? Thanx.

4b9b3361

Ответ 1

Если причина, по которой требуется доступ к предыдущему контроллеру представления, заключается в том, чтобы знать, какие данные нужно получить, я бы предположил, что вместо этого вы дадите новому контроллеру представления данные, прежде чем нажимать их на стек. Или, по меньшей мере, достаточно данных, чтобы контроллер представления знал, как получить правильные данные, например. перечисление или константа или что-то еще.

Это можно сделать с помощью пользовательского инициализатора или свойства. Взгляните на это сообщение в блоге: Передача данных между диспетчерами просмотров

Если вы используете раскадровку, вы можете использовать prepareForSegue:sender для передачи правильных данных. Хороший учебник по этому вопросу можно найти здесь: Начало раскадровки в iOS 5 Часть 2

Ответ 2

Вы можете получить предыдущий viewController, как следующий код,

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

Появится предыдущее имя viewController...

Ответ 3

В Swift:

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

Ответ 4

В Swift 3,

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

Ответ 5

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

Где сам будет текущий контроллер вида.

Ответ 6

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
    }
}

Edit:

При извлечении previousViewController данного контроллера вида, вызовите его VC1, в viewWillDisappear, VC1 уже вытащен из стека контроллера навигации. Таким образом, в этом случае вышеуказанный код не заканчивает загрузку контроллера View непосредственно над VC1 (вызовите его VC2), но контроллер представления выше VC2 (если он существует).

Чтобы избежать этой проблемы, я просто проверяю, находится ли VC1 в стеке, когда запрашивается previousViewController. Вот обновленный код:

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, будет либо находиться в верхней части навигационного стека, либо вообще отсутствует.

Ответ 7

Вы можете повторно использовать контроллеры представлений. Я бы предложил вместо того, чтобы нажать UIViewController (который содержит UITabBar, добавленный из IB) при нажатии кнопки, вы можете нажать UITabBarController, который содержит 4 контроллера просмотра (ежедневно, еженедельно, ежемесячно и ежегодно).

У UITabBarController может быть свойство перечисления (доход и расходы), и это можно назначить, когда вы нажимаете этот UITabBarController на основе нажатой кнопки. Оттуда вы можете назначить другое свойство enum (Доход и расходы) для 4 UIViewControllers для отображения правильного типа данных в каждом контроллере представления.