UINavigationControllerの新しいhidesBarsOnTap
をタブバーで模倣しようとしています。これに対する多くの回答を見てきましたが、いずれもタップしたときではなく、完全に非表示にするviewControllerでhidesBottomBarWhenPushed
を設定することを指します。
@IBAction func tapped(sender: AnyObject) {
// what goes here to show/hide the tabBar ???
}
前もって感謝します
編集:以下の提案に従って私が試した
self.tabBarController?.tabBar.hidden = true
実際にはtabBarは非表示になります(タップするとtrue/falseが切り替わります)が、アニメーションは表示されません。ただし、それは別の質問としてお願いします。
Swift私は danhによるこの素晴らしい解決策 を使用してUITabBarを優雅に非表示/表示するさまざまな方法を試し、それをSwiftに変換した後:
func setTabBarVisible(visible: Bool, animated: Bool) {
//* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) { return }
// get a frame calculation ready
let frame = self.tabBarController?.tabBar.frame
let height = frame?.size.height
let offsetY = (visible ? -height! : height)
// zero duration means no animation
let duration: TimeInterval = (animated ? 0.3 : 0.0)
// animate the tabBar
if frame != nil {
UIView.animate(withDuration: duration) {
self.tabBarController?.tabBar.frame = frame!.offsetBy(dx: 0, dy: offsetY!)
return
}
}
}
func tabBarIsVisible() -> Bool {
return (self.tabBarController?.tabBar.frame.Origin.y)! < self.view.frame.maxY
}
// Call the function from tap gesture recognizer added to your view (or button)
@IBAction func tapped(_ sender: Any?) {
setTabBarVisible(visible: !tabBarIsVisible(), animated: true)
}
マイケルキャンプソールの答えが大好き。誰かが興味を持っているなら、これは拡張と同じコードです:
Swift 2.
extension UITabBarController {
func setTabBarVisible(visible:Bool, animated:Bool) {
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) { return }
// get a frame calculation ready
let frame = self.tabBar.frame
let height = frame.size.height
let offsetY = (visible ? -height : height)
// animate the tabBar
UIView.animateWithDuration(animated ? 0.3 : 0.0) {
self.tabBar.frame = CGRectOffset(frame, 0, offsetY)
self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY)
self.view.setNeedsDisplay()
self.view.layoutIfNeeded()
}
}
func tabBarIsVisible() ->Bool {
return self.tabBar.frame.Origin.y < CGRectGetMaxY(self.view.frame)
}
}
Swift
extension UIViewController {
func setTabBarVisible(visible: Bool, animated: Bool) {
//* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time
// bail if the current state matches the desired state
if (isTabBarVisible == visible) { return }
// get a frame calculation ready
let frame = self.tabBarController?.tabBar.frame
let height = frame?.size.height
let offsetY = (visible ? -height! : height)
// zero duration means no animation
let duration: TimeInterval = (animated ? 0.3 : 0.0)
// animate the tabBar
if frame != nil {
UIView.animate(withDuration: duration) {
self.tabBarController?.tabBar.frame = frame!.offsetBy(dx: 0, dy: offsetY!)
return
}
}
}
var isTabBarVisible: Bool {
return (self.tabBarController?.tabBar.frame.Origin.y ?? 0) < self.view.frame.maxY
}
}
この質問に対する受け入れられた答えを少し適応させなければなりませんでした。それはバーを隠していましたが、私のビューは適切にサイジングされていなかったので、下部にスペースが残っていました。
次のコードは、この問題を回避するためにビューのサイズを変更しながら、タブバーの非表示を正常にアニメーション化します。
Swift 3(今では見苦しいコードが追加されました)=
func setTabBarVisible(visible: Bool, animated: Bool) {
guard let frame = self.tabBarController?.tabBar.frame else { return }
let height = frame.size.height
let offsetY = (visible ? -height : height)
let duration: TimeInterval = (animated ? 0.3 : 0.0)
UIView.animate(withDuration: duration,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseIn,
animations: { [weak self] () -> Void in
guard let weakSelf = self else { return }
weakSelf.tabBarController?.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY)
weakSelf.view.frame = CGRect(x: 0, y: 0, width: weakSelf.view.frame.width, height: weakSelf.view.frame.height + offsetY)
weakSelf.view.setNeedsDisplay()
weakSelf.view.layoutIfNeeded()
})
}
func handleTap(recognizer: UITapGestureRecognizer) {
setTabBarVisible(visible: !tabBarIsVisible(), animated: true)
}
func tabBarIsVisible() -> Bool {
guard let tabBar = tabBarController?.tabBar else { return false }
return tabBar.frame.Origin.y < UIScreen.main.bounds.height
}
旧Swift 2バージョン
func setTabBarVisible(visible: Bool, animated: Bool) {
// hide tab bar
let frame = self.tabBarController?.tabBar.frame
let height = frame?.size.height
var offsetY = (visible ? -height! : height)
println ("offsetY = \(offsetY)")
// zero duration means no animation
let duration:NSTimeInterval = (animated ? 0.3 : 0.0)
// animate tabBar
if frame != nil {
UIView.animateWithDuration(duration) {
self.tabBarController?.tabBar.frame = CGRectOffset(frame!, 0, offsetY!)
self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY!)
self.view.setNeedsDisplay()
self.view.layoutIfNeeded()
return
}
}
}
@IBAction func handleTap(recognizer: UITapGestureRecognizer) {
setTabBarVisible(!tabBarIsVisible(), animated: true)
}
func tabBarIsVisible() -> Bool {
return self.tabBarController?.tabBar.frame.Origin.y < UIScreen.mainScreen().bounds.height
}
この行をViewDidLoad()にSwiftで追加するだけです:
self.tabBarController?.tabBar.hidden = true
特定の場合にタブバーを非表示にするには、ObjCでtabBar.hidden = YESを使用します。ただし、タップイベントへの接続は試みていません。
コードは問題ありませんが、presentViewController
を使用すると、tabBarIsVisible()
は機能しません。 UITabBarController
を常に非表示にするには、この部分のみを使用します。
extension UITabBarController {
func setTabBarVisible(visible:Bool, animated:Bool) {
let frame = self.tabBar.frame
let height = frame.size.height
let offsetY = (visible ? -height : height)
UIView.animateWithDuration(animated ? 0.3 : 0.0) {
self.tabBar.frame = CGRectOffset(frame, 0, offsetY)
self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY)
self.view.setNeedsDisplay()
self.view.layoutIfNeeded()
}
}
}
Swift 3バージョン:
func setTabBarVisible(visible:Bool, animated:Bool) {
//* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) { return }
// get a frame calculation ready
let frame = self.tabBarController?.tabBar.frame
let height = frame?.size.height
let offsetY = (visible ? -height! : height)
// zero duration means no animation
let duration:TimeInterval = (animated ? 0.3 : 0.0)
// animate the tabBar
if frame != nil {
UIView.animate(withDuration: duration) {
self.tabBarController?.tabBar.frame = (self.tabBarController?.tabBar.frame.offsetBy(dx: 0, dy: offsetY!))!
return
}
}
}
func tabBarIsVisible() ->Bool {
return (self.tabBarController?.tabBar.frame.Origin.y)! < self.view.frame.midY
}
Swift 4、およびビューの外側にtabBarを配置によるアニメーション化+非表示
if let tabBar = tabBarController?.tabBar,
let y = tabBar.frame.Origin.y + tabBar.frame.height {
UIView.animate(withDuration: 0.2) {
tabBar.frame = CGRect(Origin: CGPoint(x: tabBar.frame.Origin.x, y: y), size: tabBar.frame.size)
}
}