TabBar中的UISplitViewController(UITabBarController)?

时间:2010-03-19 05:24:37

标签: ipad uitabbarcontroller iphone-sdk-3.2 uisplitviewcontroller uipopovercontroller

我处于一种情况,我需要从基于选项卡的应用程序开始,并且我需要一个或多个选项卡的拆分视图。但似乎拆分视图控制器对象无法添加到tabbarController中。 (虽然可以将tabbar对象添加到splitviewcontroller中。)

问题还可以看出:我在左侧部分有一个全屏我有一个表视图,当在表中选择任何行时,popover应该指向该行。现在,当弹出窗口中的任何行被选中时,此弹出窗口中的行将位于所选行的左下方(仅此行可见),而另一个弹出窗口将从所选行中出现。 (面包屑导航类型)

我想我清楚地解释了什么。那么有任何想法或解决方法吗?

如果我的问题不清楚,请告诉我。

谢谢,

Madhup

9 个答案:

答案 0 :(得分:19)

使用界面构建器,创建一个拆分视图控制器和一个标签栏控制器,并将它们链接到您的插座:

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

在您的app delegate 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)

我已经为UISplitViewController写了一个子类,它将监听设备方向的变化并相应地定位自己。通过这个类,我现在可以在UITabBarController中放置拆分视图,并且每个拆分视图在旋转时都会正常运行,即使它不是最前面的选项卡。我已经成功地在TexLege中部署了它并且它已被批准在App Store中使用,但您的里程可能会有所不同。请参阅Github的存储库。

随意分叉并修改它,我总是有兴趣听取有关它的评论(或抱怨)。 https://github.com/grgcombs/IntelligentSplitViewController

答案 2 :(得分:7)

我做了一个示例应用程序。并发现我们可以通过编程方式执行:

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

希望这有帮助。

答案 3 :(得分:2)

要让tabbarcontroller显示为splitviewcontroller的主视图,您应该重写tabbarcontroller以使其支持或定向(例如,使用类UITabBarController)

答案 4 :(得分:2)

请参阅我关于将拆分视图控制器改装到现有标签栏界面的帖子:http://markivsblog.blogspot.com/2010/04/retrofitting-ipad-uisplitviewcontroller.html

答案 5 :(得分:2)

我创建了一个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

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

答案 6 :(得分:1)

请注意,OS 3.2为分页视图作为标签栏视图不提供正确的支持

你可以让它“工作”但它会有错误 - 最大的问题是在另一个标签的视图上进行的方向更改通常不会正确地传播到splitview选项卡视图,当你回到它时使视图变得古怪(左侧视图占据屏幕,或缺少按钮项目等)。

我得出的结论是,我必须创建自己的splitview,以便在tabBarController中使用,因为这个问题。

我听说有传言说苹果正在修复,但现在已经好几个月没有发生iPad操作系统更新了 - 也许iPad的操作系统4会解决这个问题。

答案 7 :(得分:0)

您可以使用IB构建tabtab并将选项卡修改为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;

}

答案 8 :(得分:0)

我们成功地在iPad上使用iOS5 +的UITabViewController中安装了UISplitViewController。

长话短说:它有效:

  • 开箱即用,如果你也接受了纵向分割;
  • 带点儿 工作,如果你想隐藏在肖像中的主视图,和 只有点击按钮才会出现。

第二种情况的技巧是使用IntelligentSplitViewController(请参阅一些帖子,而不是Greg Combs)或类似地扩展UISplitVC,并注意splitview控制器的子类的委托始终是活动对象。

我们详细介绍了该过程:

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