对于 Xcode 11.3 和 iOS 13,其他答案对我没有用。但是,基于那些答案,我想到了使用 CGAffineTransform
的新解决方案。
我没有很好地测试过这个代码,但它可能真的有效。
extension UITabBarController {
func setTabBarHidden(_ isHidden: Bool) {
if !isHidden { tabBar.isHidden = false }
let height = tabBar.frame.size.height
let offsetY = view.frame.height - (isHidden ? 0 : height)
tabBar.transform = CGAffineTransform(translationX: 0, y: offsetY)
UIView.animate(withDuration: 0.25, animations: {
self.tabBar.transform = .identity
}) { _ in
self.tabBar.isHidden = isHidden
}
}
}
希望这能有所帮助。
更新于09.03.2020:
我终于找到了一个很棒的隐藏选项卡栏的实现方式,它的优点在于既可以在常见情况下工作,也可以在自定义导航控制器转换中工作。由于作者的博客相当不稳定,我将在下面留下代码。原始来源:
https://www.iamsim.me/hiding-the-uitabbar-of-a-uitabbarcontroller/
实现:
extension UITabBarController {
func setTabBar(
hidden: Bool,
animated: Bool = true,
along transitionCoordinator: UIViewControllerTransitionCoordinator? = nil
) {
guard isTabBarHidden != hidden else { return }
let offsetY = hidden ? tabBar.frame.height : -tabBar.frame.height
let endFrame = tabBar.frame.offsetBy(dx: 0, dy: offsetY)
let vc: UIViewController? = viewControllers?[selectedIndex]
var newInsets: UIEdgeInsets? = vc?.additionalSafeAreaInsets
let originalInsets = newInsets
newInsets?.bottom -= offsetY
func set(childViewController cvc: UIViewController?, additionalSafeArea: UIEdgeInsets) {
cvc?.additionalSafeAreaInsets = additionalSafeArea
cvc?.view.setNeedsLayout()
}
if hidden, let insets = newInsets { set(childViewController: vc, additionalSafeArea: insets) }
guard animated else {
tabBar.frame = endFrame
return
}
weak var tabBarRef = self.tabBar
if let tc = transitionCoordinator {
tc.animateAlongsideTransition(in: self.view, animation: { _ in tabBarRef?.frame = endFrame }) { context in
if !hidden, let insets = context.isCancelled ? originalInsets : newInsets {
set(childViewController: vc, additionalSafeArea: insets)
}
}
} else {
UIView.animate(withDuration: 0.3, animations: { tabBarRef?.frame = endFrame }) { didFinish in
if !hidden, didFinish, let insets = newInsets {
set(childViewController: vc, additionalSafeArea: insets)
}
}
}
}
var isTabBarHidden: Bool {
return !tabBar.frame.intersects(view.frame)
}
}
如果你正在处理自定义导航转场,只需传递“来自”控制器的transitionCoordinator
属性即可使动画同步:
from.tabBarController?.setTabBar(hidden: true, along: from.transitionCoordinator)
请注意,这种情况下,初始解决方案会非常不稳定。