首页 文章

UISplitviewController Master中的iOS8 TabbarController

提问于
浏览
9

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

UISplitViewController(Master)> UITabbarController> UINavigationController> UITableViewController

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

6 回答

  • 1

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

    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
        }
    
  • 1

    我想出了如何将细节放到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;
    }
    
  • 7

    这是我的解决方案 . 放置在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;
    }
    
  • 8

    没有代码,还有另一种方法可以做到这一点 .

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

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

  • 0

    像这样的子类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 .

  • 1

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

    • 使用自定义UISplitViewController(子类)

    • 重写showDetailViewController操作

    • 使用traitCollection确定UISplitViewController的类

    • 如果水平类是Compact,请让navigationController调用showViewController

    这是自定义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)
        }
    }
    

    Do not forget to the set the custom class in the storyboard.

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

相关问题