将UITabBar定位在顶部

30
我是iOS开发的初学者。我的问题是:是否可以将UITabBar放置在顶部,如何实现? 我无法将UITabBar定位在视图的顶部。

你不应该这样做。 - Fogmeister
1
@Fogmeister 为什么不呢? - nhgrif
9个回答

37

可以吗?当然可以,但这违反了人类界面指南。

屏幕截图:

竖屏 横屏 故事板

代码:

TabController.h:

#import <UIKit/UIKit.h>

@interface TabController : UITabBarController <UITabBarControllerDelegate>

@end

TabController.m:

#import "TabController.h"

@interface TabController ()

@end

@implementation TabController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.delegate = self;
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    [self.tabBar invalidateIntrinsicContentSize];

    CGFloat tabSize = 44.0;

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

    if (UIInterfaceOrientationIsLandscape(orientation))
    {
        tabSize = 32.0;
    }

    CGRect tabFrame = self.tabBar.frame;

    tabFrame.size.height = tabSize;

    tabFrame.origin.y = self.view.frame.origin.y;

    self.tabBar.frame = tabFrame;

    // Set the translucent property to NO then back to YES to
    // force the UITabBar to reblur, otherwise part of the
    // new frame will be completely transparent if we rotate
    // from a landscape orientation to a portrait orientation.

    self.tabBar.translucent = NO;
    self.tabBar.translucent = YES;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end

谢谢aviatorKen89,我尝试在Objective-C中创建(Android片段),这就是为什么我将选项卡栏显示在顶部的原因。 - AlgroDev
我不确定你在问什么。 - klcjr89
我可以只在顶部添加按钮吗? - AlgroDev
4
我猜你是从 Android 开发转向 iOS。需要记住的是,ios != Android。它们是两个完全不同的操作系统。你可能在 Android 上有一些可用的东西,但这并不意味着它在 iOS 上也能使用。实际上,它可能与 iOS 完全不兼容。在 iOS 中,用户期望选项卡栏位于底部,导航栏位于顶部。请注意,不要通过呈现意料之外的内容来让用户感到困惑。 - Fogmeister
1
有人能告诉我 HIG 中哪里写到了选项卡必须放在底部吗? - LNI
显示剩余6条评论

9

Swift3: 我通过创建一个自定义类来实现这个功能,该类针对 UITabBarController 进行了优化:

class CustomTabBarController: UITabBarController {

   @IBOutlet weak var financialTabBar: UITabBar!

    override func viewDidLoad() {
        super.viewDidLoad()
        // I've added this line to viewDidLoad
        UIApplication.shared.statusBarFrame.size.height
        financialTabBar.frame = CGRect(x: 0, y:  financialTabBar.frame.size.height, width: financialTabBar.frame.size.width, height: financialTabBar.frame.size.height)
    }

不要忘记将您的自定义类设置为TabBarController enter image description here 结果会像这样:

enter image description here


8

Swift 5

将以下代码添加到您的UITabBarViewController中:

  override func viewDidLayoutSubviews() {
    let height = navigationController?.navigationBar.frame.maxY
    tabBar.frame = CGRect(x: 0, y: height ?? 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
    super.viewDidLayoutSubviews()
  }

此功能适用于 iOS 版本大于13和小于13的设备。


1
你的意思是它适用于除了iOS 13之外的所有东西吗? - ThomasW

8

下面是一个能够运行的 Swift 3 示例,展示了 aviatorken89 的代码。

  1. First create a new file.
  2. Select source cocoa touch class.
  3. Designate subclass of: UITabBarController
  4. Name the class "CustomTabBarController" or whatever you'd like.
  5. Add the following code to the class.

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        var tabFrame:CGRect = self.tabBar.frame
        tabFrame.origin.y = self.view.frame.origin.y
        self.tabBar.frame = tabFrame
    }
    
  6. If you are using storyboard make sure to change the tab bar class to your custom class via the "Identity inspector".


1
像魔法一样运行。 - Naveed Ahmad
1
这会带来问题,即视图控制器不知道选项卡栏控制器被移动到顶部。因此,视图位置不正确。 - Slaknation

4
override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
}

storyboardenter image description here

IOS 11问题更新

以上代码在iOS 11上无效。下面是我找到的解决方法。

override func viewDidLayoutSubviews() {
    tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)

    super.viewDidLayoutSubviews()
}

你能解释一下如何在iPhoneX上实现这个吗?@mnemonic23 - PankajSharma
我认为它与其他iPhone相同。
  • 在Storyboard上创建UITabBarController
  • 对其进行子类化,例如“TabViewController”
  • 在子类中设置tabBar.frame,就像上面的代码一样。
- axunic
你是如何在选中时使选项卡按钮的下划线变成绿色的?谢谢。 - Ning

4

TabbarController的子视图会隐藏Tabbar的后面部分。 为了解决这个问题,使用以下代码:

class CustomTabBarController: UITabBarController ,UITabBarControllerDelegate{

    override func viewDidLayoutSubviews() {
        tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
        super.viewDidLayoutSubviews()
        delegate = self
        selectedViewController?.view.frame.origin = CGPoint(x: 0, y: tabBar.frame.size.height)
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
          selectedViewController?.view.frame.origin = CGPoint(x: 0, y: tabBar.frame.size.height)
    }

}

1
这在第一次显示屏幕时运行良好,但是当您转到另一个屏幕并将其弹出返回到此屏幕时,它会撤消最初设置的所有内容。您是如何解决这个问题的? - Jay

1
您可以自己制作自定义选项卡栏,但是苹果公司强烈反对模仿系统控件用于其原本不打算实现的功能。再次提醒您不要这样做,因为这会破坏您的应用程序和系统应用程序的一致性。但既然提到了它,我们来看看如何实现:要创建自定义选项卡栏,您需要创建一个包含多个按钮的视图。您还需要在UITabBar下方创建一个容器视图(因为您希望UITabBar位于顶部)。当按下按钮时,更改容器内的UIViewController。这很简单,但当然,强烈不推荐这样做。

谢谢。那么我该如何在iOS中使用(Android片段)? - AlgroDev

1

升级到xCode 11.5后,在我的控制器中添加了这段代码。适用于iOS 13。

override func viewWillLayoutSubviews() {
        renderTabPosition()
        super.viewWillLayoutSubviews()
    }
private func renderTabPosition() {
        tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height + 5)        
}

-3
如果你想要一个类似于UITabBar的东西,那么你可以创建一个自定义的UIView,并在其中添加任意数量的UIButtons。然后通过Segue将一些ViewControllers与每个按钮链接起来。完成!
你不需要自定义UITabBar。正如aviatorken89之前所说,这违反了人机界面指南。

1
请提供此“违反人机界面指南”的支持链接。 - Kalpesh Popat

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