ios - 隐藏/显示 UITabBarController 的 .tabBar(用于根视图控制器)
问题描述
我正在使用一个非常简单的设置和一个以编程方式实例化的UITabBarController
.
我的应用程序的配置来自服务器,并基于该配置动态设置viewControllers
属性。这意味着视图控制器(以及选项卡)的数量可以随时更改。
这一切都完美无缺,除了一件事。
我想隐藏viewControllers 数组tabBar
中UITabBarController
只有 1 个 viewController 的情况。
我知道您可以在 viewController 上为新推送的 viewController 设置一个标志以隐藏底栏,但这不是我想要的。
我想以编程方式控制 tabBar 的可见性,并且显然还设置了所有正确的安全边距,以便子 viewController(s) 获得所有可能的空间。
解决方案
我遇到过这样的情况,我使用了下面的代码,它成功地为我工作:
extension UITabBarController {
func setTabBarVisible(visible:Bool, duration: TimeInterval = 0.20, animated:Bool) {
if (tabBarIsVisible() == visible) { return }
let frame = self.tabBar.frame
let height = frame.size.height
let offsetY = (visible ? -height : height)
let duration = animated ? duration : 0
var safeAreaInset:CGFloat = 0
if #available(iOS 11, *) {
safeAreaInset = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
safeAreaInset += visible ? (UIApplication.shared.keyWindow?.safeAreaInsets.top ?? 0) : 0
}
if !visible, let window = self.view.window {
if let view = window.viewWithTag(999) {
view.removeFromSuperview()
}
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
window.insertSubview(view, at: 0)
view.tag = 999
view.leadingAnchor.constraint(equalTo: window.leadingAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: window.trailingAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: window.bottomAnchor).isActive = true
view.heightAnchor.constraint(equalToConstant: safeAreaInset).isActive = true
view.backgroundColor = .white
window.sendSubview(toBack: view)
}
let viewFrame = CGRect(x:self.view.frame.origin.x,y:self.view.frame.origin.y,width: self.view.frame.width, height: (self.view.frame.height + offsetY - safeAreaInset))
// animation
UIView.animate(withDuration: duration, animations: {
self.tabBar.frame.offsetBy(dx:0, dy:offsetY)
self.view.frame = viewFrame
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
}) { (finished) in
if finished {
if let view = self.view.window?.viewWithTag(999) {
self.view.window?.sendSubview(toBack: view)
}
}
}
}
func tabBarIsVisible() ->Bool {
return self.tabBar.frame.origin.y < UIScreen.main.bounds.height
}
}
你可以像这样使用它:
有一个局部变量,它将存储可见性状态并在设置时更新标签栏:
var tabbarHidden = false {
didSet {
self.tabbarController.setTabBarVisible(visible: !tabbarHidden, animated: false)
self.tabbarController.tabBar.isHidden = tabbarHidden
}
}
具有设置标签栏可见性的功能:
func setTabbarVisibility() {
if !((self.tabbarController.selectedViewController as? UINavigationController)?.topViewController?.hidesBottomBarWhenPushed ?? false) {
let count = Globals.sharedInstance.currentEvent?.bottom.count ?? 0
self.tabbarHidden = count == 0
}
}
调用此函数viewWillAppear
并viewDidLayoutSubviews
更新它,因为设置来自服务器。
推荐阅读
- ios - Swift 取一个字符串,并返回用“%%”粗体包裹的每个字符串,其他的都保持原样
- ios - 阻止 RNFirebase 请求通知权限,直到按下按钮
- flutter - 带有 SliverAppBar 的 ScrollablePositionedList 无法正常工作
- mongodb - MongoDB - 聚合:如何根据查询进行分组
- wordpress - 我们可以使用 Firebase 作为 Wordpress 网站的后端吗?
- javascript - jQuery For 循环返回除第一个字符外的未定义
- windows - Windows shell 脚本无法使现有的 IE 窗口可见?
- java - 如何设置 JTextArea 的大小?
- javascript - React Hooks:如何在选择元素内正确映射具有嵌套数组和对象的数组?(新编码器)
- wordpress - 在古腾堡代码块中键入制表符