带有UISegmentedControl的UINavigationBar部分涵盖了childViews

我已经阅读了很多关于这个和Apple文档的其他主题,但还没有为我的特定问题找到解决方案。

我的应用程序使用UITabBarController作为rootViewController ,在其中一个选项卡中,我在navigationBar有一个UISegmentedControl ,用于在三个子UITableViewController之间切换。

(在真正的应用程序中,两个childVC是一个自定义的UIViewController ,我只是为示例应用程序使用三个UITableViewController )。

segmentedControl设置和切换都可以正常工作。 出错的是只有第一个UITableViewController正确显示。 对于第二个和第三个单元,第一个单元格的一部分隐藏在navigationBar 。 当我点击这三个时,第一个仍然可以。

我做了一个小样本应用程序来显示正在发生的事情,使用非常鲜艳的颜色进行演示: https : //www.dropbox.com/s/7pfutvn5jba6rva/SegmentedControlVC.zip?dl=0

这里还有一些代码(我不使用故事板):

 // AppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. FirstViewController *fvc = [[FirstViewController alloc] init]; UINavigationController *firstNavigationController = [[UINavigationController alloc] initWithRootViewController: fvc]; SecondViewController *svc = [[SecondViewController alloc] init]; UINavigationController *secondNavigationController = [[UINavigationController alloc] initWithRootViewController: svc]; // Initialize tab bar controller, add tabs controllers UITabBarController *tabBarController = [[UITabBarController alloc] init]; tabBarController.viewControllers = @[firstNavigationController, secondNavigationController]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = tabBarController; [self.window makeKeyAndVisible]; return YES; } // FirstViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.title = @"One"; self.view.backgroundColor = [UIColor orangeColor]; UITableViewController *vc1 = [[UITableViewController alloc] init]; UITableViewController *vc2 = [[UITableViewController alloc] init]; UITableViewController *vc3 = [[UITableViewController alloc] init]; vc1.view.backgroundColor = [UIColor redColor]; vc2.view.backgroundColor = [UIColor blueColor]; vc3.view.backgroundColor = [UIColor greenColor]; self.viewControllers = @[vc1, vc2, vc3]; self.segmentTitles = @[@"Red", @"Blue", @"Green"]; self.segmentedControl = [[UISegmentedControl alloc] initWithItems: self.segmentTitles]; [self.segmentedControl addTarget: self action: @selector(segmentClicked:) forControlEvents: UIControlEventValueChanged]; self.navigationItem.titleView = self.segmentedControl; self.segmentedControl.selectedSegmentIndex = 0; // set the first child vc: UIViewController *vc = self.viewControllers[0]; [self addChildViewController: vc]; vc.view.frame = self.view.bounds; [self.view addSubview: vc.view]; self.currentVC = vc; } - (void)segmentClicked:(id)sender { if (sender == self.segmentedControl) { NSUInteger index = self.segmentedControl.selectedSegmentIndex; [self loadViewController: self.viewControllers[index]]; } } - (void)loadViewController:(UIViewController *)vc { [self addChildViewController: vc]; [self transitionFromViewController: self.currentVC toViewController: vc duration: 1.0 options: UIViewAnimationOptionTransitionFlipFromBottom animations: ^{ [self.currentVC.view removeFromSuperview]; vc.view.frame = self.view.bounds; [self.view addSubview: vc.view]; } completion: ^(BOOL finished) { [vc didMoveToParentViewController: self]; [self.currentVC removeFromParentViewController]; self.currentVC = vc; } ]; } 

显然我的问题是,为什么会发生这种情况,我该怎么做才能解决它?

编辑:添加屏幕截图。

第一个VC 第二个VC 第三个VC

编辑:根据下面的答案,我将动画块中的代码更改为:

 [self.currentVC.view removeFromSuperview]; if ([vc.view isKindOfClass: [UIScrollView class]]) { UIEdgeInsets edgeInsets = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0); [UIView performWithoutAnimation: ^{ vc.view.frame = self.view.bounds; ((UIScrollView *)vc.view).contentInset = edgeInsets; ((UIScrollView *)vc.view).scrollIndicatorInsets = edgeInsets; }]; } else { vc.view.frame = self.view.bounds; } [self.view addSubview: vc.view]; 

现在它有效。 我也将尝试使用自定义UIViewController

问题是您没有为每个表视图设置正确的内容插入。 系统会尝试为您执行此操作,但我猜您的设置过于复杂,而且只能用于viewDidLoad加载的第一个tableview。 在loadViewController:方法中,当替换当前显示的视图时,请确保将contentInsetscrollIndicatorInsets都设置为上一个视图的值。 我认为系统将设置以后设置正确的插入,以防您旋转到横向。 尝试一下。 如果没有,您需要在viewDidLayoutSubviews自行完成。