J'ai donc un bouton qui est connecté à un IBAction. Lorsque j'appuie sur le bouton, je souhaite masquer la barre d'onglets de mon application iOS avec une animation. Ce [self setTabBarHidden:hidden animated:NO];
ou ce [self.tabBarController setTabBarHidden:hidden animated:YES];
ne fonctionne pas. Ceci est mon code sans l'animation:
- (IBAction)picture1:(id)sender {
[self.tabBarController.tabBar setHidden:YES];
}
Toute aide serait grandement appréciée: D
J'essaie de garder les animations de vue à ma disposition en utilisant la formule suivante:
// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
- (void)setTabBarVisible:(BOOL)visible animated:(BOOL)animated completion:(void (^)(BOOL))completion {
// bail if the current state matches the desired state
if ([self tabBarIsVisible] == visible) return (completion)? completion(YES) : nil;
// get a frame calculation ready
CGRect frame = self.tabBarController.tabBar.frame;
CGFloat height = frame.size.height;
CGFloat offsetY = (visible)? -height : height;
// zero duration means no animation
CGFloat duration = (animated)? 0.3 : 0.0;
[UIView animateWithDuration:duration animations:^{
self.tabBarController.tabBar.frame = CGRectOffset(frame, 0, offsetY);
} completion:completion];
}
//Getter to know the current state
- (BOOL)tabBarIsVisible {
return self.tabBarController.tabBar.frame.Origin.y < CGRectGetMaxY(self.view.frame);
}
//An illustration of a call to toggle current state
- (IBAction)pressedButton:(id)sender {
[self setTabBarVisible:![self tabBarIsVisible] animated:YES completion:^(BOOL finished) {
NSLog(@"finished");
}];
}
Lorsque vous travaillez avec le scénarimage, il est facile de configurer View Controller pour masquer la barre d’onglet sur Push. Sur le View Controller de destination, cochez cette case:
Selon la documentation Apple, la propriété HidesBottomBarWhenPushed de UIViewController, une valeur booléenne, indique si la barre d'outils en bas de l'écran est masquée lorsque le contrôleur de vue est placé sur un contrôleur de navigation.
La valeur de cette propriété sur le contrôleur de vue le plus élevé détermine si la barre d'outils est visible.
L’approche recommandée pour masquer la barre d’onglet serait la suivante
ViewController *viewController = [[ViewController alloc] init];
viewController.hidesBottomBarWhenPushed = YES; // This property needs to be set before pushing viewController to the navigationController's stack.
[self.navigationController pushViewController:viewController animated:YES];
Cependant, notez que cette approche ne sera appliquée qu'à viewController respectif et ne sera pas propagée à d'autres contrôleurs de vue à moins que vous ne commenciez à définir la même propriété hidesBottomBarWhenPushed dans d'autres viewControllers avant de la placer dans la pile du contrôleur de navigation.
Swift version 3.0, utilisant une extension:
extension UITabBarController {
private struct AssociatedKeys {
// Declare a global var to produce a unique address as the assoc object handle
static var orgFrameView: UInt8 = 0
static var movedFrameView: UInt8 = 1
}
var orgFrameView:CGRect? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.orgFrameView) as? CGRect }
set { objc_setAssociatedObject(self, &AssociatedKeys.orgFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}
var movedFrameView:CGRect? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}
override open func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let movedFrameView = movedFrameView {
view.frame = movedFrameView
}
}
func setTabBarVisible(visible:Bool, animated:Bool) {
//since iOS11 we have to set the background colour to the bar color it seams the navbar seams to get smaller during animation; this visually hides the top empty space...
view.backgroundColor = self.tabBar.barTintColor
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) { return }
//we should show it
if visible {
tabBar.isHidden = false
UIView.animate(withDuration: animated ? 0.3 : 0.0) {
//restore form or frames
self.view.frame = self.orgFrameView!
//errase the stored locations so that...
self.orgFrameView = nil
self.movedFrameView = nil
//...the layoutIfNeeded() does not move them again!
self.view.layoutIfNeeded()
}
}
//we should hide it
else {
//safe org positions
orgFrameView = view.frame
// get a frame calculation ready
let offsetY = self.tabBar.frame.size.height
movedFrameView = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + offsetY)
//animate
UIView.animate(withDuration: animated ? 0.3 : 0.0, animations: {
self.view.frame = self.movedFrameView!
self.view.layoutIfNeeded()
}) {
(_) in
self.tabBar.isHidden = true
}
}
}
func tabBarIsVisible() ->Bool {
return orgFrameView == nil
}
}
Version rapide:
@IBAction func tap(sender: AnyObject) {
setTabBarVisible(!tabBarIsVisible(), animated: true, completion: {_ in })
}
// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
func setTabBarVisible(visible: Bool, animated: Bool, completion:(Bool)->Void) {
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) {
return completion(true)
}
// get a frame calculation ready
let height = tabBarController!.tabBar.frame.size.height
let offsetY = (visible ? -height : height)
// zero duration means no animation
let duration = (animated ? 0.3 : 0.0)
UIView.animateWithDuration(duration, animations: {
let frame = self.tabBarController!.tabBar.frame
self.tabBarController!.tabBar.frame = CGRectOffset(frame, 0, offsetY);
}, completion:completion)
}
func tabBarIsVisible() -> Bool {
return tabBarController!.tabBar.frame.Origin.y < CGRectGetMaxY(view.frame)
}
Essayez de définir le cadre de la barre de tabulation dans l'animation. Voir this tutorial.
Sachez simplement que c’est une mauvaise pratique de le faire, vous devriez définir afficher/masquer la barre de tabulation lorsque UIViewController
Push by définira la propriété hidesBottomBarWhenPushed
à YES
.
Réécrivez la réponse de Sherwin Zadeh dans Swift 4:
/* tab bar hide/show animation */
extension AlbumViewController {
// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
func setTabBarVisible(visible: Bool, animated: Bool, completion: ((Bool)->Void)? = nil ) {
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) {
if let completion = completion {
return completion(true)
}
else {
return
}
}
// get a frame calculation ready
let height = tabBarController!.tabBar.frame.size.height
let offsetY = (visible ? -height : height)
// zero duration means no animation
let duration = (animated ? kFullScreenAnimationTime : 0.0)
UIView.animate(withDuration: duration, animations: {
let frame = self.tabBarController!.tabBar.frame
self.tabBarController!.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY)
}, completion:completion)
}
func tabBarIsVisible() -> Bool {
return tabBarController!.tabBar.frame.Origin.y < view.frame.maxY
}
}
essayé dans Swift 3.0/iOS10/Xcode 8:
self.tabBarController?.tabBar.isHidden = true
Je le configure quand mon contrôleur est affiché: (et masqué quand je reviens, après la navigation)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.tabBarController?.tabBar.isHidden = true
}
BTW: il est préférable d'avoir un drapeau à sauvegarder s'il est affiché ou non, car les autres évents peuvent éventuellement déclencher le masquage/l'affichage
Malheureusement, je ne peux pas commenter la réponse de HixField parce que je n'ai pas assez de réputation, je dois donc laisser cette réponse séparément.
Sa réponse manque la propriété calculée pour movedFrameView
, qui est:
var movedFrameView:CGRect? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}
[Swift4.2]
Vient de créer une extension pour UITabBarController
:
import UIKit
extension UITabBarController {
func setTabBarHidden(_ isHidden: Bool, animated: Bool, completion: (() -> Void)? = nil ) {
if (tabBar.isHidden == isHidden) {
completion?()
}
if !isHidden {
tabBar.isHidden = false
}
let height = tabBar.frame.size.height
let offsetY = view.frame.height - (isHidden ? 0 : height)
let duration = (animated ? 0.25 : 0.0)
let frame = CGRect(Origin: CGPoint(x: tabBar.frame.minX, y: offsetY), size: tabBar.frame.size)
UIView.animate(withDuration: duration, animations: {
self.tabBar.frame = frame
}) { _ in
self.tabBar.isHidden = isHidden
completion?()
}
}
}