UISplitViewController в TabBar (UITabBarController)? - PullRequest
28 голосов
/ 19 марта 2010

Я нахожусь в такой ситуации, когда мне нужно начать с приложения на основе вкладок, и мне нужно разделенное представление для одной или нескольких вкладок.Но похоже, что объект контроллера с разделенным видом нельзя добавить в tabbarController.(Хотя объект tabbar может быть добавлен в splitviewcontroller).

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

Я думаю, что я ясно в том, что я объяснил.Так, ребята, есть какие-нибудь идеи или обходные пути?

Пожалуйста, дайте мне знать, если мне не ясно в моем вопросе.

Спасибо,

Madhup

Ответы [ 9 ]

19 голосов
/ 22 марта 2010

Используя построитель интерфейса, создайте контроллер разделенного представления и контроллер панели вкладок и свяжите их с вашими выходами:

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

В делегате приложения didFinishLaunchingWithOption назначьте контроллер разделения представления контроллеру панели вкладок:

splitViewController.tabBarItem = [[[UITabBarItem alloc] initWithTitle:@"Title" image:nil tag:0] autorelease];
NSArray *controllers = [NSArray arrayWithObjects:splitViewController,  /* other controllers go here */ nil];
tabBarController.viewControllers = controllers;
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];

Это создаст контроллер панели вкладок (в данном случае только 1 вкладка), который отображается правильно во всех ориентациях.

9 голосов
/ 16 ноября 2010

Я написал подкласс для UISplitViewController, который будет прослушивать изменения ориентации устройства и соответственно ориентироваться. С помощью этого класса я теперь могу размещать разделенные представления в UITabBarController, и каждое разделенное представление будет работать правильно при вращении, даже если это не самая передняя вкладка. Я успешно развернул его в TexLege , и он был одобрен для использования в App Store, но ваш пробег может отличаться. Пожалуйста, смотрите хранилище в Github.

Не стесняйтесь раскошелиться и изменить его, и мне всегда интересно услышать комментарии (или жалобы) по этому поводу. https://github.com/grgcombs/IntelligentSplitViewController

7 голосов
/ 01 апреля 2010

Я сделал пример приложения. и обнаружили, что мы можем сделать это программно, как:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

        NSMutableArray *array = [NSMutableArray array];

        NSMutableArray *tabArray = [NSMutableArray array]; 

        UISplitViewController *splitViewConntroller = [[UISplitViewController alloc] init];

        MainViewController *viewCont = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
        [array addObject:viewCont];
        [viewCont release];

        viewCont = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
        [array addObject:viewCont];
        [viewCont release];




        [splitViewConntroller setViewControllers:array];

        [tabArray addObject:splitViewConntroller];

        [splitViewConntroller release];

        array = [NSMutableArray array];

        splitViewConntroller = [[UISplitViewController alloc] init];

        viewCont = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
        [array addObject:viewCont];
        [viewCont release];

        viewCont = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
        [array addObject:viewCont];
        [viewCont release];

        [splitViewConntroller setViewControllers:array];

        [tabArray addObject:splitViewConntroller];

        [splitViewConntroller release];

        // Add the tab bar controller's current view as a subview of the window
        [tabBarController setViewControllers:tabArray];

        [window addSubview:tabBarController.view];
        [window makeKeyAndVisible];

        return YES;
    }

Надеюсь, это поможет.

2 голосов
/ 28 марта 2013

Я создал подкласс UITabBarController, который должным образом распространяет сообщения вращения на все содержащиеся в нем UISplitViewController. Это поддерживает правильное внутреннее состояние UISplitViewControllers. Однако один из методов делегата SplitViewController не вызывается, если SplitViewController не отображается, поэтому я объясняю это в методе viewWillAppear контроллера подробного представления. Я подтвердил, что это работает в iOS5.0 - iOS6.1

OSTabBarController.m

#import "OSTabBarController.h"

@implementation OSTabBarController

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    for(UIViewController *targetController in self.viewControllers){
        if(targetController != self.selectedViewController && [targetController isKindOfClass:[UISplitViewController class]]){
            [targetController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
        }
    }
}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    for(UIViewController *targetController in self.viewControllers){
        if(targetController != self.selectedViewController && [targetController isKindOfClass:[UISplitViewController class]]){
            [targetController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
        }
    }
}

@end

DetailViewController

@implementation OSDetailViewController

-(void)viewWillAppear:(BOOL)animated{
    //the splitViewController:willHideViewController:withBarButtonItem:forPopoverController: may not have been called
    if(!UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
        self.navigationItem.leftBarButtonItem = nil;
    }
}

#pragma mark - UISplitViewControllerDelegate Methods

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];

}

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
}

@end
2 голосов
/ 16 апреля 2010

Смотрите мой пост о переоборудовании контроллеров разделенного представления в существующий интерфейс панели вкладок: http://markivsblog.blogspot.com/2010/04/retrofitting-ipad-uisplitviewcontroller.html

2 голосов
/ 22 марта 2010

Чтобы позволить tabbarcontroller отображаться в качестве основного представления для splitviewcontroller, вам следует переписать tabbarcontroller, чтобы он поддерживал ориентации (например, используя категорию для класса UITabBarController)

1 голос
/ 30 июня 2010

Имейте в виду, что ОС 3.2 не обеспечивает надлежащей поддержки для разделенного вида в виде панели вкладок.

Вы можете заставить его «работать», но в нем будут ошибки - самое большое в том, что изменение ориентации, сделанное в представлении другой вкладки, часто не распространяется должным образом на представление вкладки splitview, делая представление странным, когда вы возвращаетесь к нему (левый боковой вид занимает весь экран, или отсутствует элемент кнопки и т. д.).

Я пришел к выводу, что из-за этой проблемы я должен создать свой собственный splitview для использования в tabBarController.

До меня дошли слухи, что Apple работает над исправлением, но прошло уже несколько месяцев, и никаких обновлений ОС iPad не происходило - может быть, ОС 4 для iPad справится с этим.

0 голосов
/ 08 декабря 2012

Нам удалось создать UISplitViewController внутри UITabViewController на iPad с iOS5 +.

Короче говоря, это работает:

  • из коробки, если вы принимаете разделение также на портрете;
  • с небольшим работать, если вы хотите скрыть главный вид в портретной ориентации, и показывать только после нажатия кнопки.

Хитрость во втором случае состоит в том, чтобы использовать IntelligentSplitViewController (см. Несколько публикаций выше, спасибо Грегу Комбсу) или аналогичным образом расширить UISplitVC и быть осторожным, чтобы делегат подкласса контроллера splitview всегда был живым объектом.

Мы подробно описали процесс на:

https://devforums.apple.com/message/763572#763572

0 голосов
/ 20 августа 2010

Вы можете использовать IB для создания вкладок и изменения вкладок для splitviewcontroller.

-(void) makeSplitViewController {
NSMutableArray *controllers = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
int index = 0;

for (UIViewController *controller in tabBarController.viewControllers) {
    if ([controller.tabBarItem.title isEqualToString:@"Stock"]) {
        stockDetailController = [[StockDetailController alloc] initWithNibName:@"StockDetailController" bundle:nil];

        stockMasterController = [[StockMasterController alloc] initWithStyle:UITableViewStylePlain]; 
        stockMasterController.navigationItem.title = date;
        stockMasterController.stockDetailController = stockDetailController;

        UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:stockMasterController] autorelease];

        splitViewController = [[UISplitViewController alloc] init];
        splitViewController.tabBarItem = controller.tabBarItem;
        splitViewController.viewControllers = [NSArray arrayWithObjects:nav, stockDetailController, nil];
        splitViewController.delegate = stockDetailController;

        [controllers replaceObjectAtIndex:index withObject:splitViewController];
    }

    index++;
}

tabBarController.viewControllers = controllers;

}

...