在选项卡控制器/导航控制器上方添加自定义视图?

15

我尝试了以下代码,试图让自定义视图显示在选项卡控制器上方(该选项卡控制器内部包含导航控制器的所有选项卡)。

问题是它覆盖在导航栏的上方,而我想将导航栏向下移动。

我尝试设置选项卡控制器的框架,但没有移动它。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    // Override point for customization after application launch.
    // Add the tab bar controller's current view as a subview of the window
    //self.tabBarController.view.frame = CGRectMake(0, 62, 320, 320);
    self.window.rootViewController = self.tabBarController;

    [self.window makeKeyAndVisible];

    // setting up the header view
    self.headerView = [[HeaderView alloc] initWithFrame:CGRectMake(0, 20, 320, 42)];
    [self.window addSubview:self.headerView];

    // setting up facebook stuff
    AgentSingleton *agentSingleton = [AgentSingleton sharedSingleton];
    agentSingleton.facebook = [[Facebook alloc] initWithAppId:APP_ID];

    return YES;
}
任何想法?
8个回答

40
将视图添加到tabBarController本身的视图中:
[self.tabBarController.view addSubview:yourView];

10
你可以将视图添加到窗口中:
[self.view.window addSubview:myView];

对我来说,self.view.window为空,因此添加子视图没有任何效果。 - lewis
@Lewis42 不是说这是正确的方法,但在viewDidLoad方法中,窗口属性将始终为nil。这需要在viewDidAppear方法中完成。 - Leo Dabus

9

很难找到一个好的方法来实现此功能。 UINavigationController 和 UITabBarController 的各个子视图都是私有的,尝试更改它们可能不起作用。并且,苹果没有提供工具来创建“容器”视图控制器,因此您不能轻松地将UINavigationController / UITabBarController嵌入另一个视图控制器中或自行重新创建它们。

您最好的选择可能是尝试创建自己的“容器”视图控制器,并处理某些内容不正常的情况。特别是,包含的视图控制器的parentViewController将返回nil,因此,包含视图控制器或其子控制器上的其他一些东西将被破坏(例如,interfaceOrientation属性将是错误的,presentModalViewController:animated:可能无法正常工作)。其他事情也可能会出错。

或者,您可以等待iOS的某个未来版本实际上支持我们创建容器视图控制器(如果有),然后仅支持该版本及以上版本。


5

我曾经遇到同样的问题,最终做了类似于这样的事情:

newView.frame = tabBarController.tabBar.frame
tabBarController.view.addSubview(newView)

将视图添加到tabBarController并使用当前tabbar的框架作为新视图位置的方法解决了问题。

谢谢,Xcode 11.2.1 iOS 13.1仍然可用,稍微有些变化是第一行代码,新添加的视图可以覆盖整个屏幕(包括选项卡栏)self.newView.frame = self.tabBarController?.view.frame ?? CGRect.zero - infinity_coding7

3

你能展示一下如何将这个IndicatorView添加到UITabBarController中吗?我应该在那个控制器上使用默认的addSubview方法吗?我发现了一个问题。当你推出新的viewController时,当你回到主tabbarcontroller时,这个视图会消失。 - ShadeToD
嗨,ShadeToD,你试过我建议的方法了吗?对我来说它很好用。请查看GitHub链接中的“//如何使用”。 - Egzon P.
1
是的,我已经尝试了你的代码,当你隐藏tabbar或将hidesBottomBarWhenPushed设置为true时,这个添加的视图存在问题。 - ShadeToD
是的,这种情况可能会发生。一个快速的解决方案是在viewWillAppear/viewWillDisappear上添加/删除tabBar指示器视图。 - Egzon P.

1
你可以这样做:

if let indeedTabBarController = self.tabBarController {

    let buttonHeight: CGFloat = 49 // height of tab bar
    let buttonWidth = UIScreen.main.bounds.width / 3 // in case if you have 3 tabs
    let frame = CGRect(x: 0, y: UIScreen.main.bounds.height - buttonHeight, width: buttonWidth, height: buttonHeight)
    let button = UIButton(frame: frame)
    button.addTarget(self, action: #selector(self.someAction), for: .touchUpInside)

    indeedTabBarController.view.addSubview(button)
}

0
你的意思是说“above”是指在其他内容的垂直上方吗?
还是指坐在其他内容的顶部?
有presentModalViewController:animated:,但我怀疑这不是你想要的?

垂直于其余内容之上。 - xil3
我已经将它放在顶部,但目前它遮挡了导航控制器。我需要想办法将选项卡控制器向下推... - xil3
在当前视图控制器上使用modalViewController,其中背景视图是最顶层的视图(类似于view.superview.superview.superview直到为nil)。 - dwbrito

-1
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let indeedTabBarController = self.tabBarController {
    let buttonHeight: CGFloat = view.safeAreaInsets.bottom + 44
    let buttonWidth = UIScreen.main.bounds.width
    let frame = CGRect(x: 0, y: UIScreen.main.bounds.height - buttonHeight, width: buttonWidth, height: 44)
    let vw = UIView(frame: frame)
    vw.backgroundColor = .red
    indeedTabBarController.view.addSubview(vw)
  }
}

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