UISplitviewController Master中的iOS8 TabbarController

时间:2014-08-30 09:35:58

标签: uitabbarcontroller uisplitviewcontroller ios8

我试图通过在MasterView的UINavigationController前面添加一个UITabbarController来扩展默认的Apple MasterDetail模板,所以有这样的结构:

  

UISplitViewController(Master)> UITabbarController> UINavigationController>的UITableViewController

但是如果我运行App,在更改应用程序(didFinishLaunchingWithOptions)后使用正确的ViewController,并尝试执行ShowDetails Segue,则会在iPhone上以模态方式呈现DetailsView。另一方面,iPad版本正在按预期工作。 我忘记做什么了?或者我该如何解决?

6 个答案:

答案 0 :(得分:8)

我想出了如何将详细信息放到master的UINavigationController上,而不是通过UITabBarController以模态方式呈现。

使用 UISplitViewControllerDelegate 方法

- splitViewController:showDetailViewController:sender:

如果UISplitViewController折叠,请获取主控导航控制器并将详细视图推送到此导航控制器:

- (BOOL)splitViewController:(UISplitViewController *)splitViewController
   showDetailViewController:(UIViewController *)vc
                     sender:(id)sender {
    NSLog(@"UISplitViewController collapsed: %d", splitViewController.collapsed);

    // TODO: add introspection
    if (splitViewController.collapsed) {
        UITabBarController *master = (UITabBarController *) splitViewController.viewControllers[0];
        UINavigationController *masterNavigationController = (UINavigationController *)master.selectedViewController;

        // push detail view on the navigation controller
        [masterNavigationController pushViewController:vc animated:YES];

        return YES;
    }

    return NO;
}

答案 1 :(得分:7)

只是为了更新上面的答案。由于您无法再推送导航控制器,因此您必须推送其顶视图控制器。

    func splitViewController(splitViewController: UISplitViewController, showDetailViewController vc: UIViewController, sender: AnyObject?) -> Bool {
        if splitViewController.collapsed {
            let tabBarController = splitViewController.viewControllers.first as! UITabBarController
            let selectedNavigationViewController = tabBarController.selectedViewController as! UINavigationController

            // Push view controller
            var viewControllerToPush = vc
            if let navController = vc as? UINavigationController {
                viewControllerToPush = navController.topViewController
            }
            selectedNavigationViewController.pushViewController(viewControllerToPush, animated: true)

            return true
        }

        return false
    }

答案 2 :(得分:1)

这是我的解决方案。放置在MasterViewController.m中,并记住在IB中为您的详细信息视图提供故事板ID。就我而言,“细节”。

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    if ([identifier isEqualToString:@"showDetail"] && self.splitViewController.collapsed) {
        DetailViewController *myController = (DetailViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"detail"];
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        [myController setDetailItem:object];
        [self.navigationController showViewController:myController sender:self];
         return NO;
    }
    return YES;
}

答案 3 :(得分:1)

没有代码,还有另一种方法可以做到。

在TabBarController中嵌入UINavigationController后,将TabBarController嵌入到另一个UINavigationController中。所以你将拥有:SplitViewController - >大师 - > NavCon - > TabBar - > NavCon - > TableViewController。

这样做比这容易得多,但有一个我没有找到如何修复的错误。显示的导航栏将是TabBarController的导航栏,而不是TableViewController。任何想法如何解决?

答案 4 :(得分:1)

像这样的子类TabBarController:

- (void)showViewController:(UIViewController *)vc sender:(id)sender
{
    if ([self.selectedViewController isKindOfClass:UINavigationController.class])
        [self.selectedViewController showViewController:vc sender:sender];
    else
        [super showViewController:vc sender:sender];
}

- (UIViewController*)separateSecondaryViewControllerForSplitViewController:(UISplitViewController *)splitViewController
{
    return [self.selectedViewController separateSecondaryViewControllerForSplitViewController:splitViewController];
}

- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
    [self.selectedViewController.navigationController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}

有关完整说明,请参阅this question

答案 5 :(得分:0)

这是一个基于测试splitViewController的大小类的替代方法:

  1. 使用自定义UISplitViewController(子类)
  2. 覆盖showDetailViewController操作
  3. 使用traitCollection确定UISplitViewController的类
  4. 如果水平类是Compact,请让navigationController调用showViewController
  5. 以下是自定义UISplitViewController的代码:

    import UIKit
    
    class CustomSplitViewController: UISplitViewController {
    
        override func showDetailViewController(vc: UIViewController!, sender: AnyObject!) {
    
            if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact) {
                if let tabBarController = self.viewControllers[0] as? UITabBarController {
                    if let navigationController = tabBarController.selectedViewController as? UINavigationController {
                        navigationController.showViewController(vc, sender: sender)
                        return
                    }
                }
            }
    
            super.showDetailViewController(vc, sender: sender)
        }
    }
    

    不要忘记在故事板中设置自定义类。

    在iPhone 6,iPhone 6+和iPad Air的模拟器中测试并按预期工作。