UISplitViewController в панели вкладок ( UITabBarController )?
Вопрос
Я нахожусь в такой ситуации, что мне нужно начать с приложения на основе вкладок, и в этом случае мне нужен разделенный вид для одной или нескольких вкладок.Но, похоже, что объект split view controller не может быть добавлен в TabBarController.(Хотя объект tabbar может быть добавлен в splitviewcontroller).
Проблему можно рассматривать и по-другому:У меня есть полноэкранный режим в левой части, у меня есть табличный вид, когда в таблице выбрана любая строка, должно появиться всплывающее окно, указывающее на эту строку.Теперь, когда выбрана любая строка во всплывающем окне, строки в этом всплывающем окне отображаются слева под выбранной строкой (будет видна только эта строка), а из выбранной строки выходит другое всплывающее окно.(Тип навигации по хлебным крошкам)
Я думаю, мне ясно то, что я объяснил.Итак, ребята, есть какие-нибудь идеи или обходные пути?
Пожалуйста, дайте мне знать, если я не проясню свой вопрос.
Спасибо,
Мэдхап
Решение 3
Я составил образец заявления.и обнаружил, что мы можем сделать это программно, например:
- (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;
}
Надеюсь это поможет.
Другие советы
Используя конструктор интерфейсов, создайте контроллер разделенного представления и контроллер панели вкладок и свяжите их со своими торговыми точками:
@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];
Это создаст контроллер панели вкладок (в данном случае только с одной вкладкой), который будет отображаться правильно во всех ориентациях.
Я написал подкласс для UISplitViewController, который будет отслеживать изменения ориентации устройства и ориентироваться соответствующим образом.С помощью этого класса я теперь могу размещать разделенные представления внутри UITabBarController, и каждое разделенное представление будет вести себя правильно при повороте, даже если это не самая передняя вкладка.Я успешно развернул это в ТексЛеге и оно было одобрено для использования в App Store, но ваш опыт может отличаться.Пожалуйста, посмотрите репозиторий на Github.
Не стесняйтесь создавать и модифицировать его, и мне всегда интересно услышать комментарии (или жалобы) по этому поводу. https://github.com/grgcombs/IntelligentSplitViewController
Чтобы контроллер панели вкладок отображался в качестве основного представления для контроллера разделенного представления, вам следует переписать контроллер панели вкладок, чтобы он поддерживал ориентации (скажем, используя категорию для класса UITabBarController).
См. мой пост о модернизации контроллеров разделенного представления в существующий интерфейс панели вкладок: http://markivsblog.blogspot.com/2010/04/retrofitting-ipad-uisplitviewcontroller.html
Я создал подкласс UITabBarController, который правильно передает сообщения о ротации всем содержащимся в нем UISplitViewControllers.Это поддерживает правильное внутреннее состояние 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
Деталивиевконтроллер
@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
Имейте в виду, что ОС 3.2 делает не оказывать должной поддержки для разделенного просмотра в виде панели вкладок.
Вы можете заставить его «работать», но в нем будут ошибки — самая большая из них заключается в том, что изменение ориентации, сделанное в представлении другой вкладки, часто не распространяется на представление вкладки разделенного просмотра должным образом, из-за чего представление становится дурацким, когда вы возвращаетесь к нему (левая сторона вид захватывает экран, или элемент панели кнопок отсутствует и т. д.).
Я пришел к выводу, что из-за этой проблемы мне нужно создать собственное разделенное представление для использования в tabBarController.
До меня доходили слухи, что Apple работает над исправлением, но прошли уже несколько месяцев, а обновлений ОС iPad не было — возможно, OS 4 для iPad решит эту проблему.
Вы можете использовать IB для создания вкладок и изменения вкладок в контроллере SplitView.
-(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;
}
Нам удалось установить UISplitViewController внутри UITabViewController на iPad с iOS5 +.
короче говоря, это долгая история:это работает:
- из коробки, если вы принимаете разделение также в портретном режиме;
- с небольшой работой, если вы хотите, чтобы основной вид был скрыт в портретном режиме, и чтобы он отображался только при нажатии кнопки.
Хитрость во втором случае заключается в использовании IntelligentSplitViewController (см. Несколько сообщений выше, спасибо Грегу Комбсу) или аналогичном расширении UISplitVC и будьте осторожны, чтобы делегат подкласса контроллера splitview всегда был живым объектом.
Мы подробно описали этот процесс на: