iOS 7:自定义容器视图控制器,UINavigationController作为子视图控制器

时间:2014-03-23 09:51:43

标签: ios7 uiviewcontroller uinavigationbar uicontainerview ios7-statusbar

我想编写一个自定义的全屏容器视图控制器,目的是将UINavigationController作为子视图控制器放入其中。 UINavigationController的视图将填充容器视图控制器的视图,使其看起来像UINavigationController是根视图控制器。 (人们可能希望做这样的事情,比如创建由Facebook推广的滑动侧边栏菜单UI。)

我所做的工作除了在呈现另一个视图控制器时出现故障,当iPhone处于横向时,它会隐藏状态栏。通常,导航栏在状态栏消失时向上滑动,在重新出现时向下滑动。相反,当导航栏向下滑动时,导航栏会保持原样,当假设向下滑动时,导航栏首先定位,状态栏与其重叠,然后跳转到状态栏下方的正确位置。基本上,我试图使UINavigationController的行为与它不在自定义容器视图控制器中的行为一样。

以下是您可以运行以查看问题的一些代码,但如果您不想这样做,请查看 ContainerViewController 类,该类实现最小的自定义容器视图控制器。 我的自定义容器视图控制器中缺少什么导致此问题?当我使用UITabBarController作为容器视图控制器时,它可以工作,所以看起来我好像我在实施中遗漏了一些东西。

如果您想要,请阅读以下内容:

如果您想运行示例代码以查看问题,请参阅概述。在 AppDelegate 中定义了一个名为 MODE 的预处理器定义,以便以三种方式有条件地编译应用程序。

  • MODE == 1 时, ViewController 位于UINavigationController中。然后你可以按"出现"按钮以显示 ViewControllerWithStatusBarHidden ,然后您可以按" Dismiss"按钮以关闭此视图控制器。此应用程序模式显示了我正在寻找的行为。

  • MODE == 2 时,我们与 MODE == 1 中的内容相同,只是UINavigationController位于 ContainerViewController < / em>的。此应用程序模式显示了我目前的不良行为。

  • MODE == 3 时,我们与 MODE == 1 中的内容相同,只是UINavigationController位于UITabBarController内。此应用程序模式显示可以获得我正在寻找的行为。

再次,要查看问题,只需按&#34; Present&#34;按钮,然后是&#34; Dismiss&#34; iPhone处于横向时按钮。

CODE

四个班级:

  1. ContainerViewController
  2. 的AppDelegate
  3. 的ViewController
  4. ViewControllerWithStatusBarHidden
  5. ContainerViewController.h

    #import <UIKit/UIKit.h>
    
    @interface ContainerViewController : UIViewController
    
    @property (nonatomic) UIViewController * viewController;
    
    @end
    

    ContainerViewController.m

    #import "ContainerViewController.h"
    
    // This custom container view controller only has one child view controller,
    // whose view fills up the view of the container view controller.
    @implementation ContainerViewController
    
    - (UIViewController *)viewController {
        if (self.childViewControllers.count > 0) {
            return [self.childViewControllers firstObject];
        }
        else {
            return nil;
        }
    }
    
    - (void)setViewController:(UIViewController *)viewController {
        UIViewController *previousViewController = [self.childViewControllers firstObject];
        if ((previousViewController == nil && viewController != nil)
            || (previousViewController != nil && viewController == nil)
            || (previousViewController != nil && viewController != nil
                && previousViewController != viewController))
        {
            if (previousViewController != nil) {
                // Remove the old child view controller.
                [previousViewController willMoveToParentViewController:nil];
                [previousViewController.view removeFromSuperview];
                [previousViewController removeFromParentViewController];
            }
    
            if (viewController != nil) {
                // Add the new child view controller.
                [self addChildViewController:viewController];
                self.viewController.view.frame = self.view.bounds;
                self.viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
                [self.view addSubview:self.viewController.view];
                [self.viewController didMoveToParentViewController:self];
            }
        }
    }
    
    - (UIViewController *)childViewControllerForStatusBarHidden {
        return self.viewController;
    }
    
    - (UIViewController *)childViewControllerForStatusBarStyle {
        return self.viewController;
    }
    
    @end
    

    AppDelegate.h

    #import <UIKit/UIKit.h>
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    
    @property (strong, nonatomic) UIWindow *window;
    
    @end
    

    AppDelegate.m

    #import "AppDelegate.h"
    
    #import "ViewController.h"
    #import "ContainerViewController.h"
    
    #define MODE 2  // Mode can be 1, 2, or 3.
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
        ViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    
    #if MODE == 1   // No container view controller.
    
        self.window.rootViewController = nav;
    
    #elif MODE == 2 // Use custom container view controller.
    
        ContainerViewController *container = [[ContainerViewController alloc] initWithNibName:nil bundle:nil];
        container.viewController = nav;
        self.window.rootViewController = container;
    
    #elif MODE == 3 // Use tab bar controller as container view controller.
    
        UITabBarController *tab = [[UITabBarController alloc] initWithNibName:nil bundle:nil];
        tab.viewControllers = @[nav];
        self.window.rootViewController = tab;
    
    #endif
    
        [self.window makeKeyAndVisible];
        return YES;
    }
    
    @end
    

    ViewController.h

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    @end
    

    ViewController.m

    #import "ViewController.h"
    
    #import "ViewControllerWithStatusBarHidden.h"
    
    // This view controller will serve as the content of a navigation controller.
    // It also provides a button in the navigation bar to present another view controller.
    @implementation ViewController
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            self.title = @"Title";
            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Present"
                                                                                      style:UIBarButtonItemStylePlain
                                                                                     target:self
                                                                                     action:@selector(pressedPresentButton:)];
        }
        return self;
    }
    
    - (void)loadView {
        self.view = [[UIView alloc] init];
        self.view.backgroundColor = [UIColor whiteColor];
    }
    
    - (void)pressedPresentButton:(id)sender {
        ViewControllerWithStatusBarHidden *vc = [[ViewControllerWithStatusBarHidden alloc] initWithNibName:nil bundle:nil];
    
        [self presentViewController:vc animated:YES completion:nil];
    }
    
    @end
    

    ViewControllerWithStatusBarHidden.h

    #import <UIKit/UIKit.h>
    
    @interface ViewControllerWithStatusBarHidden : UIViewController
    
    @end
    

    ViewControllerWithStatusBarHidden.m

    #import "ViewControllerWithStatusBarHidden.h"
    
    // This view controller is meant to be presented and does two things:
    // (1) shows a button to dismiss itself and (2) hides the status bar.
    @implementation ViewControllerWithStatusBarHidden
    
    - (void)loadView {
        self.view = [[UIView alloc] init];
        self.view.backgroundColor = [UIColor yellowColor];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeSystem];
        [dismissButton setTitle:@"Dismiss" forState:UIControlStateNormal];
        [dismissButton addTarget:self
                          action:@selector(pressedDismissButton:)
                forControlEvents:UIControlEventTouchUpInside];
        dismissButton.frame = CGRectMake(100, 100, 100, 100);
    
        [self.view addSubview:dismissButton];
    }
    
    - (void)pressedDismissButton:(id)sender {
        [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (BOOL)prefersStatusBarHidden {
        return YES;
    }
    
    //- (NSUInteger)supportedInterfaceOrientations {
    //    return UIInterfaceOrientationMaskPortrait;
    //}
    
    @end
    

0 个答案:

没有答案