Arm1.ru

Использование UINavigationController вместе с UITabBarController

Появилась нужна использовать в проекте и UINavigationController, и UITabBarController одновременно. Два способа как это сделать.

Создадим пустой проект. Прописывать контроллеры будем вручную. Итак, у нас есть AppDelegate.h и AppDelegate.m.

Способ 1. UINavigationController внутри UITabBarController. (от @vox_humana)

В этом способе в приложении всегда есть Tab Bar, он всегда виден и между табами всегда можно переключаться. Внутри одного из табов (или можно сделать во всех) есть вид с UINavigationController, в котором можно делать перемещение между видами с помощью push и pop.

Создадим два новый файла типа UIViewController subclass (с галкой with XIB for user interface). Назовём их, скажем, FirstViewController и SecondViewController. Это будут два наших вида, которые будут выводиться в двух табах.

Наш AppDelegate.h в пустом проекте выглядит так:

#import <UIKit/UIKit.h>
 
@interface AppDelegate : UIResponder <UIApplicationDelegate>
 
@property (strong, nonatomic) UIWindow *window;
 
@end

Нам нужно добавить новую @property c UITabBarController:

#import <UIKit/UIKit.h>
 
@interface AppDelegate : UIResponder <UIApplicationDelegate>
 
@property (strong, nonatomic) UIWindow *window;
 
@property (strong, nonatomic) UITabBarController *tabBarController;
 
@end

Далее идём в AppDelegate.m. Здесь нужно импортировать созданные FirstViewController и SecondViewController, а также сделать @synthesize для табов:

#import "AppDelegate.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
 
@implementation AppDelegate
 
@synthesize window = _window;
@synthesize tabBarController = _tabBarController;

Внутри метода didFinishLaunchingWithOptions прописываем следующее:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // создаём окно для приложения по размеру экрана
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
    // создаём два экземпляра UIViewController
    UIViewController *viewController1, *viewController2;
	
    // первый вид инициализируем с интерфейсом нашего первого контроллера
    viewController1 = [[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil]];
 
    // второй вид инициализируем с интерфейсом нашего второго контроллера
    viewController2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    
    // подключаем наши виды к таб-бару
    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
	
    // как основной контроллер приложению ставим tabBarController
    self.window.rootViewController = self.tabBarController;
	
    [self.window makeKeyAndVisible];
    return YES;
}

Теперь при запуске у нас появится таб-бар внизу экрана. В каждом табе будет по контроллеру. Первый контроллер (viewController1) будет иметь в себе UINavigationController, что позволит нам делать push и pop видов. Для примера добавим ещё один UIViewController subclass (с галкой with XIB for user interface). Назовём его MyViewController. Таким образом у нас уже будет 3 UIViewController в проекте:

Использование UINavigationController вместе с UITabBarController

Поскольку у нас viewController1 (он же FirstViewController) содержит в себе UINavigationController, то добавим в него какое-нибудь действие, чтобы перейти в наш контроллер. Сначала в начале FirstViewController.m сделаем #import "DetailViewController.h", затем добавим метод:

- (IBAction)pushToMyController:(id)sender {
    MyViewController * childControl = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
    [[self navigationController] pushViewController:childControl animated:YES];
}

Ну и само собой не забудем объявить его в FirstViewController.h:

- (IBAction)pushToMyController:(id)sender;

Добавим в FirstViewController.xib кнопку и свяжем её через Connection Inspector с нашим action:

Использование UINavigationController вместе с UITabBarController

Готово. Можно запускать. На выходе получаем вот такой результат:

По такому принципу сделано приложение Dropbox для iPhone, например. Скачать готовый пример.

Способ 2. UITabBarController внутри UINavigationController.

Начинаем с того, что создаём RootViewController. Ему нужно создать @property:

@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

Добавить в xib-файл UITabBarController, связать его в Connections Inspector. Создаём два вида в проекте - FirstViewController и SecondViewController, для UITabBarController, что внутри RootViewController.xib привязываем табы к этим видам.

Приведу начало файла AppDelegate.m:

#import "AppDelegate.h"
#import "RootViewController.h"
 
@implementation AppDelegate
 
@synthesize window = _window;
@synthesize viewController = _viewController;
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // создаём окно
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];	
	
    // создаём главный контроллер
    self.viewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
	
    // создаём UINavigationController
    navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    
    // назначаем главным контроллером UINavigationController
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

Общая суть в том, что self.window.rootViewController - это UINavigationController. У приложения есть RootViewController со своим xib. Его можно оставить пустым, но ему нужно прописать @property:

@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

Когда вид RootViewController загружается - мы сразу делаем push в наш tabBarController. Таким образом первое, что видно при запуске - это табы и верхнюю панель с кнопкой назад, которую в этом месте можно скрыть и показывать только дальше где-то.

Главный плюс - внутри видов, которые грузятся внутри UITabBarController - можно в коде делать перемещение основного экрана в другие виды и возвращаться обратно. Видео:

По такому принципу сделано приложение ВКонтакте для iPhone. Реализовано в моём примере, пожалуй, не идеально, при желании можно допилить, но работает. Скачать пример.

На будущее пригодится, заодно сам ещё раз всё проделал и закрепил.

keyboard_return back