UITableViewController在UITabBarController中嵌套UINavigationController

4

我的问题

我正在使用一个UITabBarController嵌套在UINavigationController中。在UITabBarController中有三个tableviews。如图所示,第一个table view显示正确,而其他两个tableviews部分被导航栏遮挡。我该如何解决这个问题?

enter image description here enter image description here enter image description here

我的层次结构:

  • Root: UINavigationController
    • UITabBarController
      • UITableViewController (table1,table2,table3)

以下是我的代码:

AppDelegate.m

#import "AppDelegate.h"
#import "TableViewController.h"
@interface AppDelegate()
@property UINavigationController* nav;
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    TableViewController* table1 = [[TableViewController alloc]init];
    TableViewController* table2 = [[TableViewController alloc]init];
    TableViewController* table3 = [[TableViewController alloc]init];
    table1.title = @"table1";
    table2.title = @"table2";
    table3.title = @"table3";
    UITabBarController* t = [[UITabBarController alloc] init];
    [t setViewControllers:@[table1,table2,table3]];
    self.nav = [[UINavigationController alloc] initWithRootViewController:t];
    [self.window setRootViewController:self.nav];
    [self.window makeKeyAndVisible];
    return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application{}
- (void)applicationDidEnterBackground:(UIApplication *)application{}
- (void)applicationWillEnterForeground:(UIApplication *)application{}
- (void)applicationDidBecomeActive:(UIApplication *)application{}
- (void)applicationWillTerminate:(UIApplication *)application{}
@end

TableViewController.m

#import "TableViewController.h"
@implementation TableViewController
- (id)initWithStyle:(UITableViewStyle)style{
    self = [super initWithStyle:style];
    if (self) {}
    return self;
}
- (void)viewDidLoad{
    [super viewDidLoad];
    [self.tabBarController.view layoutSubviews];
}
- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];
}
#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 10;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell* c = [[UITableViewCell alloc] init];
    [c.textLabel setText:[NSString stringWithFormat:@"%d", indexPath.row]];
    return c;
}
@end

你尝试过在你的UITableViewController中设置self.tableView.contentInset = UIEdgeInsetsMake(64.0f, 0.0, 0.0, 0.0)吗? - iiFreeman
请查看这个答案:https://dev59.com/H2Qn5IYBdhLWcg3wIkMF#18785646 - LE SANG
self.tableView.contentInset = UIEdgeInsetsMake(64.0f, 0.0, 0.0, 0.0); 这行代码将使得table2和table3看起来正常,但也会使table1下降64个点。 - user94602
@১২৩:谢谢,它有效。顺便问一下,你的名字是用什么语言写的? - user94602
我迟到了,但是...任何遇到同样问题的人都应该取消勾选“自动调整滚动视图插入”...从属性检查器中进行设置就可以解决问题。 - Abu Ul Hassan
2个回答

5
通常情况下,层级结构如下:
UITabBarController
    - UINavigationController
        - UITableViewController

为什么您想要把导航控制器放在顶部?尝试使用一个装满导航控制器的选项卡栏重新组织。


我正在尝试这样做,因为我希望当选择table1中的一行时,它将推送一个新的全屏视图控制器,同时保留导航栏。我不想在新推出的视图中显示选项卡栏。我也不想简单地设置选项卡栏消失,因为那会不够流畅。 - user94602
选项卡控制器的设计并不适用于除视图层次结构顶部以外的任何位置。因此,即使您找到了一个解决此问题的方法(因为它可能与控制器层次结构无关),随着开发的进行,您肯定会遇到其他问题。我建议您尝试隐藏选项卡栏来解决这个问题。 - coneybeare
尽管我不太愿意承认,UITabBarController的文档说必须将其设置为层次结构的根。 “在部署标签栏界面时,您必须将此视图安装为窗口的根视图。与其他视图控制器不同,标签栏界面永远不应作为另一个视图控制器的子级安装。” - Kenny Wyland
1
@user94602,现在你可以使用以下代码将新的视图控制器全屏显示:newViewController.hidesBottomBarWhenPushed = YES;,这个方法适用于coneybeare所提到的层次结构。 - iTSangar

1
我昨天遇到了同样的问题,决定绕过它。只有一个类会妨碍,所以这是重写代码的方法:

DRTabBarController.h

//
// Created by Dan Rosenstark on 2/28/15.
// Copyright (c) 2015 Confusion Studios LLC. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface DRTabBarController : UIViewController <UITabBarDelegate>;

@property (nonatomic, strong) NSArray *viewControllers;
@property (nonatomic, strong) UITabBar *tabBar;
@property (nonatomic, strong) UIView *mainView;

@end

DRTabBarController.m

//
// Created by dr2050 on 2/28/15.
// Copyright (c) 2015 Confusion Studios LLC. All rights reserved.
//

#import "DRTabBarController.h"


@implementation DRTabBarController {


}


- (instancetype)init {
    self = [super init];
    if (self) {
        self.tabBar = [[UITabBar alloc] init];
        self.tabBar.delegate = self;
        self.tabBar.tintColor = [UIColor whiteColor];
        self.tabBar.barStyle = UIBarStyleBlack;
        self.tabBar.backgroundColor = [UIColor blackColor];

        self.mainView = [[UIView alloc] init];
    }
    return self;
}

- (void)viewDidLoad {
    [self.view addSubview:self.tabBar];
    [self.view addSubview:self.mainView];
}

- (void)setViewControllers:(NSArray *)viewControllers {
    _viewControllers = viewControllers;

    NSMutableArray *tabBarItems = [NSMutableArray array];
    for (UIViewController *controller in viewControllers) {
        UITabBarItem *item = controller.tabBarItem;
        [tabBarItems addObject:item];
    }
    self.tabBar.items = tabBarItems;
}


- (void)viewWillAppear:(BOOL)animated {
    [self.tabBar setSelectedItem:self.tabBar.items.firstObject];
    [self tabBar:self.tabBar didSelectItem:self.tabBar.items.firstObject];
}

- (void)viewDidAppear:(BOOL)animated {



}

-(void)viewDidLayoutSubviews {
    CGRect frame = self.view.bounds;
    UITabBarController *throwaway = [[UITabBarController alloc] init];
    frame.size.height = throwaway.tabBar.frame.size.height;
    frame.origin.y = self.view.bounds.size.height - frame.size.height;
    self.tabBar.frame = frame;
    self.tabBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;

    frame = self.view.bounds;
    frame.size.height -= self.tabBar.frame.size.height;

    float navbarHeight = self.navigationController.navigationBar.frame.size.height;
    // cannot use UIApplication.sharedApplication.statusBarFrame.size.height because
    // reports are not right with in-call status bar
    float statusBarHeight = UIApplication.sharedApplication.statusBarHidden ? 0 : 20;
    float topBarHeight = navbarHeight + statusBarHeight;

    frame.origin.y += topBarHeight;
    frame.size.height -= topBarHeight;
    self.mainView.frame = frame;
    self.mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
    int index = [self.tabBar.items indexOfObject:item];
    NSArray *subviews = self.mainView.subviews;
    for (UIView *view in subviews) {
        [view removeFromSuperview];
    }
    UIView *view = [[self.viewControllers objectAtIndex:index] view];
    view.frame = self.mainView.bounds;
    view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.mainView addSubview:view];
}


@end

注意: 这里有一个神奇的变量 -- 20 -- 它用于呼叫状态栏,与周围的导航栏完全不同...

任何帮助都将不胜感激,但是确实有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接