更改 UITabBar 高度
Posted
技术标签:
【中文标题】更改 UITabBar 高度【英文标题】:Change UITabBar height 【发布时间】:2014-05-27 11:25:20 【问题描述】:我使用UITabBarController
作为根视图,并且应用支持 ios 6 及更高版本。项目类层次结构如下。
UITabBarController
- tab1
- UINavigationController
- UIViewController
- UIViewController
.
.
- tab2
- UINavigationController
- UIViewController
- UIViewController
.
.
.
- tab3
- UIViewController
- tab4
- UIViewController
我使用下面的代码在上面的层次结构中的一个 UIViewControllers(在 UINavigationController
内)中更改 UITabBar
的高度。
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
的高度来达到这样的效果:?
【问题讨论】:
你可以改变默认的tabbar高度,但是你需要继承UITabBarController,我之前做过,我写在***.com/questions/16740824/tab-bar-with-large-icons/… 发现这行得通 -> ***.com/a/27494228/1484378 我想你也可以只设置一个高度限制,它似乎对我有用。 【参考方案1】:我遇到了这个问题,我能够解决它。
您必须将以下代码添加到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 的类中,但什么也没发生 你的viewWillLayoutSubviews
实现应该调用super,可能是第一行。
@Dklionsk 它可以调用super
,但它不必:The default implementation of this method does nothing.
(来自文档)
@dmirkitanov 对于UIViewController
是正确的,但对于UITabBarController
可能不是正确的
将 viewWillLayoutSubviews
更改为 viewDidLayoutSubviews
适用于 iOS 13。【参考方案2】:
对于iOS 8.2,Xcode 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”是什么意思?如何连接它?谢谢! 你去你的故事板。点击viewcontroller,到Xcode右侧的“view inspector”。在第三个选项卡(看起来像报纸)下,您会找到“班级”标签。占位符灰色文本应显示“UIViewController”。在那里输入视图控制器文件的名称,例如。 “DNMainTabVC”。之后,“DNMainTabVC”旁边的框中将出现一个箭头。这意味着视图控制器文件 (.swift) 已连接到情节提要元素。您在“DNMainTabVC.swift”中写的任何内容都会对故事板 VC 产生影响。 @MS_iOSDeveloper 知道了。所以它正在选择自定义类。我以为你的意思是一些“拖动”动作来“连接”。我得到它的工作。谢谢你的解释!【参考方案3】:Swift3.0、Swift 4.0 兼容
Pre-iPhone X 默认标签栏高度:49pt
iPhone X 默认标签栏高度:83pt
支持包括 iPhone X 屏幕尺寸在内的所有 iOS 设备的通用解决方案如下所示:
捕获UITabBar的默认高度:
fileprivate lazy var defaultTabBarHeight = tabBar.frame.size.height ()
调整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
【讨论】:
这将使 tabBar 在动画视图更改时跳转(如隐藏状态栏) @jakedunc 我认为这是 S. Azzopardi 所说的问题,我将这段代码放在 viewDidLayoutSubviews() 中,它工作正常。 @ioio007 您好,这适用于 iPhone x 和其他设备。但是当我增加高度时,UIView 底部会根据增加值隐藏。帮我解决。 嗨@Saravanan,看起来您的问题与此答案下方的评论相同:***.com/a/44293634/7144402 UITabBarViewController 类中的 viewWillLayoutSubviews 改为 viewDidLayoutSubviews 就可以了。它对我有用。【参考方案4】:在 XCode 9.0 和 Swift 4
中测试正如之前的答案所建议的那样——继承UITabBar
并覆盖sizeThatFits
,但将height
标记为@IBInspectable
,因此可以在Interface Builder中进行设置:
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
在Identity Inspector (⌥⌘3) 中为UITabBar
设置CustomTabBar
类:
然后在属性检查器(⌥⌘4)中设置所需的Height
(大于0.0
):
【讨论】:
您是否考虑过制作一个扩展而不是自定义类。然后在扩展名中指定@IBInspectable var height
。如果可能的话,可以避免指定自定义类的第二步。
在 iPhone X 上效果不佳。你必须使用这个解决方案:***.com/a/50346008/1702909【参考方案5】:
创建一个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
希望这会奏效。
【讨论】:
太棒了!到目前为止,这是我见过的最好的解决方案。因为它不直接修改框架,而是改变预期的大小!太好了! 这个答案在内部视图控制器的自动布局方面没有副作用,应该是公认的答案。 当我们以编程方式制作标签栏控制器时如何使用它?【参考方案6】:斯威夫特 4
extension UITabBar
override open func sizeThatFits(_ size: CGSize) -> CGSize
var sizeThatFits = super.sizeThatFits(size)
sizeThatFits.height = 60 // adjust your size here
return sizeThatFits
【讨论】:
【参考方案7】: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 有同样的问题。如果你把 Alvin 的代码放在 viewDidLoad() 中会出现空白,但如果你按照建议将它放在 viewWillLayoutSubviews() 中则不会出现【参考方案8】:Swift 3.0+ 在下面的代码中将 200 替换为您想要的高度。
extension UITabBar
override open func sizeThatFits(_ size: CGSize) -> CGSize
return CGSize(width: UIScreen.main.bounds.width, height: 200)
【讨论】:
小心!关于在运行时使用哪种方法实现的行为未定义 - 原始来自 UITabbar 类或您的扩展 像魅力一样工作 您应该不使用 Swift 扩展(或 Objective-C 类别,就此而言)覆盖方法。如果您想使用sizeThatFits()
方法,请改用此解决方案:***.com/a/46425620/538491【参考方案9】:
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 元素,并且当我尝试通过覆盖 @987654325 来设置 tabBarController
的 tabBar
时@属性,它显示一个空的tabBar(没有项目)
guard let window = UIApplication.shared.keyWindow 在 iOS 13.0 中已弃用。所以请更新。【参考方案10】:
在以前的答案的基础上为 Swift 3 更新。
子类 UITabController 并确保将新的自定义类分配给 UITabController 的 Identity Inspector。
Swift 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,我将视图固定到底部视图,例如:NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutAttribute.equal, toItem: view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0)
我找到了safeAreaInsets
和safeAreaLayoutGuide
,但该功能仅适用于iOS 11 及更高版本。你指的是这个吗?
是的,您可以尝试在 iOS 11 及更高版本上使用 view.safeAreaLayoutGuide.bottomAnchor,其中 view 是 VC 的主视图。在 iOS 11 下,固定到 VC 的 bottomLayoutGuide.topAnchor。目前,您正在使用视图的底部,并且视图可能会低于这些底部参考线。
@john 也,仅供参考,为方便起见,我在 VC 扩展中创建了 4 个变量,提供了简单的使用约束(重复左右和顶部):扩展 UIViewController var safeBottomAnchor: NSLayoutYAxisAnchor if #available (iOS 11.0, *) return view.safeAreaLayoutGuide.bottomAnchor else return bottomLayoutGuide.topAnchor 【参考方案11】:
出于某种原因,@Rushikesh 的回答在 iOS 10 之前运行良好,但我在 iOS 11 和 Swift 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
【讨论】:
【参考方案12】: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);
【讨论】:
【参考方案13】:使用安全区域编辑了 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
【讨论】:
【参考方案14】:您可以通过子类化来修改标签栏的高度。实际上我很久以前就这样做了。 xcode 6.0
override func sizeThatFits(_ size: CGSize) -> CGSize
return CGSize(width: super.sizeThatFits(size).width, height: 60)
这应该返回其默认宽度,高度为 60pts。
【讨论】:
【参考方案15】:这也是一种方法
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
【讨论】:
【参考方案16】:适用于所有屏幕尺寸: 将 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
【讨论】:
【参考方案17】: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
【讨论】:
【参考方案18】:只需在安全区域底部添加更多插图:
additionalSafeAreaInsets.bottom = 40
【讨论】:
这结合向下移动标签栏项目标题和图像,使它们居中可能是最简洁的解决方案。谢谢!【参考方案19】: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;
【讨论】:
【参考方案20】: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
对我来说工作得很好。
【讨论】:
【参考方案21】:它帮助了我
override func viewDidLayoutSubviews()
super.viewWillLayoutSubviews()
tabBar.frame.size.height = 60
tabBar.frame.origin.y = view.frame.height - 60
【讨论】:
这与this other answer(和其他)中的解决方案相同。 在回答已有答案的旧问题时,请确保提供新颖的解决方案或比现有答案更好的解释。 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案22】:对于 UITabBarController 子类
从 UITabBar 创建一个子类
class CustomTabBar : UITabBar
override open func sizeThatFits(_ size: CGSize) -> CGSize
super.sizeThatFits(size)
var sizeThatFits = super.sizeThatFits(size)
sizeThatFits.height = 200
return sizeThatFits
并在构造函数中设置类
init()
super.init(nibName: nil, bundle: nil)
object_setClass(self.tabBar, CustomTabBar.self)
【讨论】:
以上是关于更改 UITabBar 高度的主要内容,如果未能解决你的问题,请参考以下文章
UINavigationBar + UITabBar 的可用屏幕高度
Objective-C中带有圆角和自定义高度的UITabbar