我想编写一个自定义的全屏容器视图控制器,目的是将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处于横向时按钮。
四个班级:
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