更改UITabBar高度

76

我将UITabBarController用作根视图,该应用程序支持iOS 6及以上版本。项目类层次结构如下。

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

我在上述层次结构中的一个UIViewController中使用以下代码更改UITabBar的高度(该UIViewController位于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的高度,以实现类似于这样的效果?

输入图像描述


1
你可以更改默认的tabbar高度,但是你需要子类化UITabBarController,我以前做过这个,我在http://stackoverflow.com/questions/16740824/tab-bar-with-large-icons/16742065#16742065上写下了它。 - limon
发现这个可行 -> https://dev59.com/yGAf5IYBdhLWcg3wqUON#27494228 - keji
我认为你也可以只设置一个高度约束,这对我来说似乎有效。 - giovannipds
24个回答

7

由于某些原因,@Rushikesh的答案在iOS 10上运行得非常好,但我在iOS 11和Swift 3.2上遇到了一些问题。

每次我点击一个新标签时,tabBar都会改变其框架。

我通过将代码放入viewDidLayoutSubviews()函数中而不是viewWillLayoutSubviews()来解决这个问题。

Swift 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

只需在安全区域底部添加更多的内嵌:

additionalSafeAreaInsets.bottom = 40

enter image description here


1
这个方案很可能是最整洁的,它将选项卡栏项目标题和图像下移并居中。谢谢! - Balázs Vincze

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
   } 
}

4

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
    }
}

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
    }

2
class 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
    }


}

对我来说运行良好。


对我来说会导致无限循环。我认为viewDidLayoutSubviews被再次调用,因为tabBar的框架被修改了。 - Siamaster

1

iPhoneX的高度与众不同,因此如果我们将其移动到较小的高度,则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;
    }
}

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