Контроллер панели вкладок внутри контроллера навигации или общий доступ к корневой панели навигации

Я пытаюсь реализовать пользовательский интерфейс, подобный в приложении Tweetie, который ведет себя так: контроллер верхнего уровня, похоже, является контроллером навигации, чей корневой вид представляет собой табличное представление "Учетные записи". Если вы нажмете на любую учетную запись, она перейдет на второй уровень, который имеет панель вкладок в нижней части. Каждый элемент табуляции показывает другой список и позволяет вам развернуться дальше (последующие уровни не отображают панель вкладок).

Итак, это похоже на иерархию реализации:

  • UINavigationController
    • Учетные записи: UITableViewController
    • UITabBarController
      • Tweets: UITableViewController
        • Подробный вид твита/пользователя/etc
      • Ответов: UITableViewController
      • ...

Это похоже на работу [^ 1], но, по-видимому, не поддерживается в соответствии с документацией SDK для -pushViewController:animated: (выделено мной):

viewController: контроллер представления, который помещается в стек. Он не может быть экземпляром контроллера панели вкладок.

Я хотел бы избегать частных API и т.п., но я не уверен, почему это использование явно запрещено, даже если оно работает нормально. Кто-нибудь знает причину?

Я подумал о том, чтобы установить контроллер панели вкладок в качестве основного контроллера, причем каждая из вкладок содержит отдельные навигационные контроллеры. Проблема заключается в том, что каждому контроллеру nav необходимо разделить один контроллер корневого представления (а именно таблицу "Учетные записи" в Tweetie) - это, похоже, не работает: нажатие контроллера таблицы на второй контроллер управления, похоже, удаляет его от первой. Не говоря уже о том, что все бухгалтерские книги при выборе другой учетной записи, вероятно, были бы болью.

Как я должен реализовать это правильно?

[^ 1]: контроллер панели вкладок должен быть подклассифицирован, чтобы элемент навигации контроллера панели табуляции на этом уровне оставался в синхронизации с выбранным элементом навигации вкладки, а отдельному контроллеру таблицы табуляции нужно было подтолкнуть их соответствующие подробные представления до self.tabBarController.navigationController вместо self.navigationController.

Ответ 1

Два предыдущих ответа правильно поняли - я не использую UITabBarController в Tweetie. Очень легко написать пользовательский XXTabBarController (простой подкласс UIViewController), который с удовольствием попадает в стек навигационного контроллера, но все еще живет философией "контроллера представления". Каждая "вкладка" в определенном для учетной записи представлении (Tweets/Replies/Messages) является его собственным контроллером представления, и, насколько это возможно, они обмениваются на экране с помощью plain-ol UITabBarController.

Ответ 2

Я создаю приложение, которое использует аналогичную навигационную среду для Tweetie. Я написал сообщение о том, как это сделать в моем блоге www.wiredbob.com, который также ссылается на исходный код. Это полный шаблон, который вы можете использовать и использовать в качестве основы для другого проекта. Удачи!

Ответ 3

Можно добавить UITabBar в любой UIViewController. Таким образом, вам фактически не нужно нажимать UITabBarController и, следовательно, оставаться в рамках принципов API Apple.

В построителе интерфейса UITabBar находится под "Windows, представлениями и барами" в Cocoa сенсорной библиотеке.

Ответ 4

Я делаю это в нескольких моих приложениях. Трюк добавления панели вкладок в приложение на основе navigationController - НЕ использовать TabBarController. Добавьте панель представления в представление, сделайте контроллер представления для этого вида TabBarDelegate и ответьте на выбор пользователя на панели вкладок в коде контроллера вида.

Я использую Tab Bars для добавления дополнительных представлений в представление панели вкладок в виде под-представлений, для перезагрузки представления таблицы с различными наборами данных, для перезагрузки UIPickerView и т.д.

Ответ 5

Я боролся за прошлый час, чтобы реализовать UITabBar, потому что он будет скрыт, когда я попытаюсь отобразить мое представление; то я нашел это post:

В принципе, убедитесь, что вы ввели новое представление под панелью вкладок в соответствии с этой строкой кода:

[self.view insertSubview:tab2ViewController.view belowSubview:myTabBar];

Ответ 6

Вот как я это сделал. На самом деле это приводит к тому, что контроллер навигации настраивается на навигационный контроллер. Он работает нормально. Я не нашел нигде в документации, что яблоко не поддерживает этот способ. Может ли кто-нибудь дать мне ссылку на это предупреждение?

Если это правда, возможно ли, что Apple отказывается публиковать мое приложение в appstore?

-(void)setArrayAndPushNextController
{
    MyFirstViewController *myFirstViewController = [[MyFirstViewController alloc] init];
    MySecondViewController *mySecondViewController = [[MySecondViewController alloc] init];

    myFirstViewController.array = self.array;


    NSArray *array = [[NSArray alloc] initWithObjects:myFirstViewController, mySecondViewController, nil];
    UITabBarController *tab = [[UITabBarController alloc] init];
    tab.viewControllers = array;

    [array release];

    UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"first title" image:nil tag:1];
    UITabBarItem *item2 = [[UITabBarItem alloc] initWithTitle:@"second title" image:nil tag:2];

    myFirstViewController.tabBarItem = item1;
    mySecondViewController.tabBarItem = item2;

    [self stopAnimatingSpinner];

    [self.navigationController pushViewController:tab animated:YES];

    [tab release];
    [item1 release];
    [item2 release];
}

Ответ 7

В моем приложении контроллер корневого представления является контроллером UINavigation. В определенный момент в приложении мне нужно отобразить UITabBar. Я попытался реализовать UITabBar в UIView в иерархии навигации, как и некоторые из предыдущих сообщений, и это работает. Но я обнаружил, что мне больше нравится поведение по умолчанию, которое предоставляет контроллер табуляции, и я нашел способ использовать UITabBarController с контроллером UINavigation:

1) Когда я хочу отобразить представление UITabBarController, я делаю это:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = myUiTabBarControllerInstance;

2) Когда я хочу вернуться туда, где был в иерархии навигации, я делаю это:

appDelegate.window.rootViewController = myNavControllerInstance;

Ответ 8

Это может быть достигнуто простым вложением TabBarController в контроллер навигации. В раскадровке:

  • Перетащите ViewController
  • Нажмите на сцену ViewController
  • Нажмите на редакторе → Вставить в → Контроллер навигации.
  • Перетащите кнопку на том же ViewController.
  • Перетащите элемент TabBarController
  • Подключите кнопку на ViewController к элементу TabBarController, нажав кнопку Segue Action.

В этом случае только контроллер TabBarController RootViewController будет находиться в стеке контроллера навигации. Все элементы TabBarItems будут иметь панель навигации наверху, и пользователь может перейти на главный экран в любое время, независимо от выбранного TabBarItem

Это можно сделать на любом ViewController в стеке контроллера навигации.

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

Ответ 9

Я написал сообщение в блоге о том, как я подошел к этой проблеме. Для меня использование модального представления было более простым решением, чем создание пользовательской реализации вкладки.

http://www.alexmedearis.com/uitabbarcontroller-inside-a-uinavigationcontroller/