提问人:Saren Inden 提问时间:10/3/2023 更新时间:10/5/2023 访问量:21
iOS 在弹出视图控制器后不显示标签栏,hidesBottomBarWhenPush 设置为 true
iOS doesn't show tab bar after popping a view controller with hidesBottomBarWhenPushed sets to true
问:
我对 .hidesBottomBarWhenPushed
它在按下(隐藏标签栏)和弹出(显示标签栏)时正常工作。但我有这个小宝石:
- 有一个 UITabBarController,它有一个 UINavigationController 作为选项卡,其中包含一个 UIViewController
- 在堆栈上推送一个新的 UIViewController,此视图控制器已在 init 中设置为 true。标签栏已正确隐藏
hidesBottomBarWhenPushed
- 此视图中有一个按钮,用于执行两个操作
- 以模式呈现新的视图控制器(全屏,用于工作表演示,这有效)
- 弹出当前视图控制器
- 关闭以模式呈现的视图
- 初始 UINavigationController 与其子项一起显示,但选项卡栏仍处于隐藏状态
因此,可悲的是,由于没有官方函数可以调用UITabBarController来隐藏或显示UITabBar,因此我没有看到解决此问题的好方法。也没有重新评估当前状态的功能。
如果演示稍有延迟,一切正常(但有些利益相关者不希望这样......
因此,这是重现该错误的完整代码(假设一个新项目具有情节提要,其中有一个 UITabBarController 作为入口点,其中有一个 UINavigationController,其中 作为其子项)ViewController
请原谅“丑陋”,它只是简单的演示代码
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
tabBarController?.tabBar.isTranslucent = false
view.backgroundColor = .red
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.navigationController?.pushViewController(VC2(), animated: true)
}
}
}
class VC2: UIViewController {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
hidesBottomBarWhenPushed = true
navigationItem.leftBarButtonItem = UIBarButtonItem(systemItem: .close, primaryAction: UIAction(handler: { _ in
let nvc = self.navigationController
let vc = UINavigationController(rootViewController: VC3())
vc.modalPresentationStyle = .fullScreen
// With a delay it all works fine
// DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
nvc?.present(vc, animated: true)
// }
self.navigationController?.popViewController(animated: true)
}), menu: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .blue
}
}
class VC3: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
navigationItem.leftBarButtonItem = UIBarButtonItem(systemItem: .close, primaryAction: UIAction(handler: { _ in
self.dismiss(animated: true)
}))
}
}
答:
0赞
Saren Inden
10/5/2023
#1
似乎一个“hacky”解决方案是对“拥有”UINavigationController进行修改
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Determine if we are in the invalid state
guard
let tabBarController,
tabBarController.tabBar.isHidden,
let last = children.last,
!last.hidesBottomBarWhenPushed
else {
return
}
// Force the navigation controller to reevaluate the current `hidesBottomBarWhenPushed`
pushViewController(UIViewController(), animated: false)
popViewController(animated: false)
// The safe space is shown but the tab bar is still set to hidden
tabBarController.tabBar.isHidden = false
}
对我来说,这在没有任何视觉伪影的情况下工作,但它也有点骇人听闻,这总是一个有问题的解决方案。
0赞
Saren Inden
10/5/2023
#2
我找到了另一种解决方案。仅当订单类似于
vc.present(modalVC, animated: true)
...
self.navigationController?.popViewController(animated: false)
而不是相反(所以现在必须在流行音乐之前完成)
var animatedPop = true
if let presentedViewController, presentedViewController.modalPresentationStyle == .fullScreen {
animatedPop = false
}
navigationController?.popViewController(animated: animatedPop)
显然,出于某种神奇的原因,系统确实正确评估了hidesBottomBarWhenPushed
评论