更改UITabBar的高度


70

UITabBarController用作根视图,并且应用程序支持iOS 6及更高版本。项目类的层次结构如下。

UITabBarController
  - tab1
    - UINavigationController
      - UIViewController
      - UIViewController
      .
      .
  - tab2
    - UINavigationController
      - UIViewController
      - UIViewController
      .
      .
      .
  - tab3
    - UIViewController
  - tab4
    - UIViewController

我使用下面的代码来更改上面层次结构UITabBar中的一个UIViewControllers(位于里面UINavigationController)的高度。

CGRect tabbarFrame = self.tabBarController.tabBar.frame;
tabbarFrame.size.height += 60;
self.tabBarController.tabBar.frame = tabbarFrame;

但是它并没有改变高度。UITabBar以默认高度显示。尽管记录其值会打印更改的值,如下所示。

<UITabBar: 0xb528f60; frame = (0 431; 320 109); autoresize = W+TM; layer = <CALayer: 0xb529080>>

如何更改UITabBar高度以达到以下目的:?

在此处输入图片说明


您可以更改默认的标签栏高度,但需要继承UITabBarController的子类,之前已经完成过,我在stackoverflow.com/questions/16740824/tab-bar-with-large-icons
limon 2014年


我认为您也可以设置一个高度限制,这似乎对我有用。
giovannipds '18

Answers:


141

我遇到了这个问题,并且能够解决它。

您必须将以下代码添加到类的子UITabBarController类中。

const CGFloat kBarHeight = 80;

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    CGRect tabFrame = self.tabBar.frame; //self.TabBar is IBOutlet of your TabBar
    tabFrame.size.height = kBarHeight;
    tabFrame.origin.y = self.view.frame.size.height - kBarHeight;
    self.tabBar.frame = tabFrame;
}

迅速:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    tabBar.frame.size.height = kBarHeight
    tabBar.frame.origin.y = view.frame.height - kBarHeight
}

您可以指定更多吗?我已将此代码添加到扩展TabBarController的类中,
但未

8
您的viewWillLayoutSubviews实现应调用super,可能作为第一行。
Dklionsk 2015年

1
@Dklionsk它可以调用super,但不必调用:(The default implementation of this method does nothing.来自文档)
dmirkitanov

1
@dmirkitanov这是正确的,UIViewController但可能并非如此UITabBarController
Alex Pretzlav 16-2-23

15
更改viewWillLayoutSubviewsviewDidLayoutSubviews可在iOS 13中使用
。– arlomedia

43

对于iOS 8.2Xcode 6.2 Swift语言:

为您的UITabBarController(类型UITabBarController)创建一个“ DNMainTabVC.swift”(DeveloperNameMainTabViewController.swift文件),并将其连接到情节提要VC。

添加以下行:

override func viewWillLayoutSubviews() {
    var tabFrame = self.tabBar.frame
    // - 40 is editable , the default value is 49 px, below lowers the tabbar and above increases the tab bar size
    tabFrame.size.height = 40
    tabFrame.origin.y = self.view.frame.size.height - 40
    self.tabBar.frame = tabFrame
}

这对我有用。


@MS_iOSDeveloper:“将其连接到Storyboard VC”是什么意思?如何连接呢?谢谢!
摇滚

1
您进入情节提要。单击viewcontroller,然后转到Xcode右侧的“视图检查器”。在第三个标签(看起来像报纸)下,您会找到“类别”标签。占位符灰色文本应显示为“ UIViewController”。在此键入您的viewcontroller文件的名称,例如。“ DNMainTabVC”。之后,箭头将出现在“ DNMainTabVC”旁边的框中。这意味着视图控制器文件(.swift)已连接到情节提要元素。您在“ DNMainTabVC.swift”中编写的内容都会对情节提要VC产生影响。
MB_iOSDeveloper 2015年

@MS_iOSDeveloper知道了。因此它正在选择自定义类。我以为您是说要“连接”一些“拖拽”动作。我知道了。感谢您的解释!
摇滚

38

XCode 9.0Swift 4中测试

如先前答案中所建议-继承UITabBar和重写sizeThatFits,但标记height@IBInspectable,因此可以在“界面生成器”中进行设置:

import UIKit

class CustomTabBar : UITabBar {
    @IBInspectable var height: CGFloat = 0.0

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        if height > 0.0 {
            sizeThatFits.height = height
        }
        return sizeThatFits
    }
}

身份检查器(⌥⌘3)中设置CustomTabBar类:UITabBar

标签栏身份检查器

然后在“属性”检查器(⌥⌘4)中设置所需的值Height(大于):0.0

标签栏属性检查器


您是否考虑过扩展而不是自定义类。然后@IBInspectable var height在扩展名中指定 。如果可能的话,可以避免指定自定义类的第二步。
维平·约翰尼

1
没有行之有效的iPhone X.你必须使用此解决方案:stackoverflow.com/a/50346008/1702909
英德日赫Rohlík

37

Swift3.0,兼容Swift 4.0

iPhone X之前的默认标签栏高度:49pt

iPhone X默认标签栏高度:83pt

一个支持所有iOS设备(包括iPhone X屏幕尺寸)的通用解决方案如下所示:

  1. 捕获UITabBar的默认高度:

    fileprivate lazy var defaultTabBarHeight = { tabBar.frame.size.height }()
    
  2. 调整UITabBar的高度:

        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            let newTabBarHeight = defaultTabBarHeight + 16.0
    
            var newFrame = tabBar.frame
            newFrame.size.height = newTabBarHeight
            newFrame.origin.y = view.frame.size.height - newTabBarHeight
    
            tabBar.frame = newFrame
        }
    

1
动画视图更改时,这会使tabBar跳起来(例如隐藏状态栏)
jakedunc 18/09/4

2
@jakedunc我认为这是S. Azzopardi所说的问题,我将这段代码放在viewDidLayoutSubviews()中,并且工作正常。
ioio007 '18

@ ioio007您好,此方法适用于iPhone x和其他设备。但是当我增加高度时,UIView底部根据增加值隐藏。帮助我获得解决方案。
Saravanan19年

嗨,@ Saravanan,您的问题似乎与此答案下方的评论相同:stackoverflow.com/a/44293634/7144402
ioio007

在UITabBarViewController类中将viewWillLayoutSubviews更改为viewDidLayoutSubviews可以正常工作。它为我工作。
萨希尔·奥默

29

创建一个类型的自定义子类UITabBar,然后实现以下方法:

@implementation CustomTabBar
#define kTabBarHeight = // Input the height we want to set for Tabbar here
-(CGSize)sizeThatFits:(CGSize)size
{
    CGSize sizeThatFits = [super sizeThatFits:size];
    sizeThatFits.height = kTabBarHeight;

    return sizeThatFits;
}
@end

希望这会起作用。


1
大!到目前为止,这是我见过的最好的解决方案。因为它不会直接修改框架,而是会更改预期的尺寸!大!
vilanovi

就内部视图控制器的自动布局而言,此答案没有副作用,它应该是公认的答案。
tsuz '18

以编程方式使选项卡栏控制器成为可能时,如何使用它?
EI队长v2.0

14

对于Swift 4

extension UITabBar {

     override open func sizeThatFits(_ size: CGSize) -> CGSize {
     var sizeThatFits = super.sizeThatFits(size)
     sizeThatFits.height = 60 // adjust your size here
     return sizeThatFits
    }
 }

11

Swift 2.0:

var tabBar:UITabBar?

override func viewWillLayoutSubviews() {
    var tabFrame: CGRect = self.tabBar!.frame
    tabFrame.size.height = 60
    tabFrame.origin.y = self.view.frame.size.height - 60
    self.tabBar!.frame = tabFrame
}

在Swift 2.2中不再起作用。它在原始的标签栏框架下方留下了一个空白空间
jaytrixz

@jaytrixz也有同样的问题。如果您将Alvin的代码放在viewDidLoad()中,则会出现空白,但如果按照建议将其放在viewWillLayoutSubviews()中,则
不会出现

10

Swift 3.0+在下面的代码中将200替换为所需的高度。

   extension UITabBar {
        override open func sizeThatFits(_ size: CGSize) -> CGSize {
            return CGSize(width: UIScreen.main.bounds.width, height: 200)
        }
    }

小心!对于在运行时使用哪种方法实现,行为未定义-源自UITabbar类或您的扩展程序
Alexander Larionov

像魅力一样工作
rockdaswift

你应该被覆盖使用斯威夫特扩展(或Objective-C类,对于这个问题)的方法。如果要使用此sizeThatFits()方法,请改用以下解决方案:stackoverflow.com/a/46425620/538491
Roberto

10

Swift 4&与iPhone X兼容

class CustomTabBar : UITabBar {

@IBInspectable var height: CGFloat = 65.0

override open func sizeThatFits(_ size: CGSize) -> CGSize {
    guard let window = UIApplication.shared.keyWindow else {
        return super.sizeThatFits(size)
    }
    var sizeThatFits = super.sizeThatFits(size)
    if height > 0.0 {

        if #available(iOS 11.0, *) {
            sizeThatFits.height = height + window.safeAreaInsets.bottom
        } else {
            sizeThatFits.height = height
        }
    }
    return sizeThatFits
}
}

我用内部的这种方法定义extension,因为我创造所有的UI元素编程,当我试图设置tabBar我的tabBarController通过重写tabBar属性,它会显示一个空的TabBar(没有项目)
mauricioconde

在iOS 13.0中不建议使用guard let window = UIApplication.shared.keyWindow。因此,请更新。
Chandan Jee

7

以先前的答案为基础,并为Swift 3进行更新。

子类化UITabController,并确保将新的自定义类分配给UITabController的Identity Inspector。

斯威夫特3.0

class MainTabBarController: UITabBarController {

    override func viewWillLayoutSubviews() {
        var newTabBarFrame = tabBar.frame

        let newTabBarHeight: CGFloat = 60
        newTabBarFrame.size.height = newTabBarHeight
        newTabBarFrame.origin.y = self.view.frame.size.height - newTabBarHeight

        tabBar.frame = newTabBarFrame
    }
}

警告:如果在标签栏下方留有空白,请确保已将这段代码放在viewWillLayoutSubviews()中,而不是viewDidLoad()中。


这行得通,但是由于高度增加,某些视图被选项卡栏阻塞了。任何想法如何解决呢?
约翰(John)

嘿,约翰。您是否将它们固定在安全区域底部边缘?
Kqtr

@Kqtr,您好,我将视图固定在底部视图上,例如: NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutAttribute.equal, toItem: view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0) 我发现了safeAreaInsetssafeAreaLayoutGuide但该功能仅适用于iOS 11及更高版本。这是您的意思吗?
约翰

是的,您可以尝试在iOS 11及更高版本上使用view.safeAreaLayoutGuide.bottomAnchor,其中view是VC的主视图。在iOS 11以下,固定到VC的bottomLayoutGuide.topAnchor。当前,您正在使用视图的底部,并且该视图的位置可能会低于这些底部的参考线。
Kqtr

仅供参考,@ john,为了方便起见,我在VC扩展中创建了4个变量,该变量提供了简单的使用约束(对于左右和顶部重复):扩展UIViewController {var safeBottomAnchor:NSLayoutYAxisAnchor {如果#available(iOS 11.0,*){ view.safeAreaLayoutGuide.bottomAnchor} else {return bottomLayoutGuide.topAnchor}}}
Kqtr

7

出于某种原因,@ Rushikesh的答案在iOS 10之前运行良好,但是我在iOS 11Swift 3.2上遇到了一些问题。

每次我触摸新标签页时,tabBar都会更改其框架。

我通过将代码放在viewDidLayoutSubviews()函数中而不是viewWillLayoutSubviews()

迅捷3:

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    var tabFrame            = tabBar.frame
    tabFrame.size.height    = 65
    tabFrame.origin.y       = view.frame.size.height - 65
    tabBar.frame            = tabFrame
}

5

Xamarin实现:

public override void ViewWillLayoutSubviews()
{
    base.ViewWillLayoutSubviews();
    const float newTabBarHeight = 40f;
    TabBar.Frame = new CGRect(TabBar.Frame.X, TabBar.Frame.Y + (TabBar.Frame.Height - newTabBarHeight), TabBar.Frame.Width, newTabBarHeight);
}

5

使用安全区编辑了Kiarash Asar的答案:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    var safeAreaBottomInset: CGFloat = 0.0

    if #available(iOS 11.0, *) {
        safeAreaBottomInset = view.safeAreaInsets.bottom
    }

    let newTabBarHeight: CGFloat = {{myDesiredHeight}} + safeAreaBottomInset

    var newFrame = tabBar.frame
    newFrame.size.height = newTabBarHeight
    newFrame.origin.y = view.frame.size.height - newTabBarHeight

    tabBar.frame = newFrame
}

4

您可以通过子类化来修改标签栏的高度。我实际上是很久以前做的。xcode 6.0

override func sizeThatFits(_ size: CGSize) -> CGSize {
    return CGSize(width: super.sizeThatFits(size).width, height: 60)
}

这应该返回其默认宽度,高度为60pts。


4

这也是做到这一点的一种方法

extension UITabBar {

override public func sizeThatFits(size: CGSize) -> CGSize {
    super.sizeThatFits(size)
    var sizeThatFits = super.sizeThatFits(size)
    sizeThatFits.height = 71 // or whatever height you need
    return sizeThatFits
   } 
}

3

使用所有屏幕大小的方法:将tabBarHeight设置为(tabBar的原始高度-20)这一点很重要,因此您以后可以在viewDidLayoutSubviews中使用它,也比硬编码所需的大小更好。由于该尺寸可能不适用于所有屏幕。

窗户安全区域插图可在标签栏高度的底部保留必要的填充,以保持与屏幕底部边缘的距离。

var tabBarHeight = CGFloat()

override func viewDidLoad() {
        super.viewDidLoad()
        tabBarHeight = self.tabBar.frame.height - 20
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        var tabFrame = self.tabBar.frame
        guard let window = UIApplication.shared.keyWindow else {return}
        tabFrame.size.height = tabBarHeight + window.safeAreaInsets.bottom
        self.tabBar.frame = tabFrame
    }

1

iPhoneX具有不同的高度,因此如果我们将高度调低,则TabX形状在iPhoneX中会很糟糕

- (void)viewWillLayoutSubviews
{
    int requiredHeight = 55;
    CGRect tabFrame = self.tabBar.frame;
    if (tabFrame.size.height < requiredHeight)
    {
        tabFrame.size.height = requiredHeight;
        tabFrame.origin.y = self.view.frame.size.height - requiredHeight;
        self.tabBar.frame = tabFrame;
    }
}

0

Swift 5.3.1,XCode 11 +,iOS 14:

import UIKit

class CustomTabBar: UITabBar {
    let height: CGFloat = 62
    
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        guard let window = UIApplication.shared.connectedScenes
                .filter({$0.activationState == .foregroundActive})
                .map({$0 as? UIWindowScene})
                .compactMap({$0})
                .first?.windows
                .filter({$0.isKeyWindow}).first else {
            return super.sizeThatFits(size)
        }

        var sizeThatFits = super.sizeThatFits(size)
        if #available(iOS 11.0, *) {
            sizeThatFits.height = height + window.safeAreaInsets.bottom
        } else {
            sizeThatFits.height = height
        }
        return sizeThatFits
    }
}

0

TabBarVC类:UITabBarController {

//MARK:- Variable
let HEIGHT_TAB_BAR:CGFloat = 500

override func viewDidLoad() {
    super.viewDidLoad()
    
    // Do any additional setup after loading the view.
}


override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    var tabFrame = self.tabBar.frame
    tabFrame.size.height = HEIGHT_TAB_BAR
    tabFrame.origin.y = self.view.frame.size.height - HEIGHT_TAB_BAR
    self.tabBar.frame = tabFrame
}

}

对我来说很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.