Supprimer le texte de l'élément de la barre d'onglets, afficher uniquement l'image

89

Question simple, comment puis-je supprimer le texte de l'élément de la barre d'onglets et n'afficher que l'image?

Je veux que les articles du bar aiment dans l'application Instagram:

entrez la description de l'image ici

Dans l'inspecteur de xcode 6, je supprime le titre et choisis une image @ 2x (50px) et une @ 3x (75px). Cependant, l'image n'utilise pas l'espace libre du texte supprimé. Des idées pour obtenir la même image d'élément de barre d'onglets que dans l'application Instagram?

Vote favorable
la source
1
en utilisant ""pour le titre, peut-être?
holex
1
Le réglage des décalages n'est qu'une astuce, la bonne réponse est un peu plus bas. Vous devriez utiliser navigationItem.title = "some title"
Davit Siradeghyan

Réponses:

129

Vous devriez jouer avec la imageInsetspropriété de UITabBarItem. Voici un exemple de code:

let tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "more")
tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)

Les valeurs à l'intérieur UIEdgeInsetsdépendent de la taille de votre image. Voici le résultat de ce code dans mon application:

entrez la description de l'image ici

Mustafa
la source
25
Vous pouvez également ajuster les incrustations d'image dans l'inspecteur.
Vote positif
Les nombres magiques sont une mauvaise idée. Veuillez consulter ma réponse pour une manière universellement compatible d'accomplir la même chose.
Ezekiel Victor le
4
Cela ne fonctionne plus dans iOS 11 - si vous double-cliquez sur l'onglet actif, cela doublera les inserts pour une raison quelconque.
Ben Gotow
@BenGotow même problème vous avez une solution?
Dixit Akabari
@DixitAkabari d'autres personnes ont déjà publié de bonnes solutions pour iOS 11
Pranav Kasetti
77
// Remove the titles and adjust the inset to account for missing title
for(UITabBarItem * tabBarItem in self.tabBar.items){
    tabBarItem.title = @"";
    tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0);
}
ddiego
la source
1
Au lieu de supprimer le titre, changez la couleur du texte pour effacer. Le titre peut être utile.
Eduardo Mauro
1
Kodos à Eduardo! M'a fait réaliser qu'une bonne option est également de définir un décalage UIO vertical sur le titre de l'article PositionAjustement
Julius
2
Où mettez-vous cela dans votre contrôleur TabBar personnalisé?
UKDataGeek
69

Voici comment procéder dans un storyboard.

Effacez le texte du titre et définissez l'encart d'image comme la capture d'écran ci-dessous

entrez la description de l'image ici

N'oubliez pas que la taille de l'icône doit suivre directives de conception de pomme

entrez la description de l'image ici

Cela signifie que vous devriez avoir 25px x 25px pour @ 1x, 50px x 50px pour @ 2x, 75px x 75px pour @ 3x

nuynait
la source
45

L'utilisation de l'approche avec la définition de la propriété de chaque UITabBarItems titlesur "" et la mise à jour imageInsetsne fonctionnera pas correctement si le contrôleur de vue self.titleest défini. Par exemple, si self.viewControllersUITabBarController est incorporé UINavigationControlleret que vous avez besoin que le titre soit affiché dans la barre de navigation. Dans ce cas, définissez UINavigationItemdirectement le titre en utilisant self.navigationItem.title, pas self.title.

Stefan
la source
2
Cela semble être une méthode plus propre. +1 @Oleg cela devrait être marqué comme réponse.
akseli
29

Version rapide de la réponse ddiego

Compatible avec iOS 11

Appelez cette fonction dans viewDidLoad de chaque premier enfant de viewControllers après avoir défini le titre de viewController

Meilleur entrainement:

Alternativement comme @daspianist suggéré dans les commentaires

Créez une sous-classe semblable à celle-ci BaseTabBarController: UITabBarController, UITabBarControllerDelegate et placez cette fonction dans le viewDidLoad de la sous-classe

func removeTabbarItemsText() {

    var offset: CGFloat = 6.0

    if #available(iOS 11.0, *), traitCollection.horizontalSizeClass == .regular {
        offset = 0.0
    }

    if let items = tabBar.items {
        for item in items {
            item.title = ""
            item.imageInsets = UIEdgeInsets(top: offset, left: 0, bottom: -offset, right: 0)
        }
    }
}
korgx9
la source
2
Excellente fonction! Vous pouvez également créer une sous-classe comme celle-ci class BaseTabBarController: UITabBarController, UITabBarControllerDelegateet mettre cette fonction dans la sous-classeviewDidLoad
daspianist
26

Si vous utilisez des storyboards, ce serait votre meilleure option. Il parcourt tous les éléments de la barre d'onglets et pour chacun d'eux, il définit le titre sur rien et rend l'image en plein écran. (Vous devez avoir ajouté une image dans le storyboard)

for tabBarItem in tabBar.items!
{
   tabBarItem.title = ""
   tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}
Marcos Reboucas
la source
Il est bon de noter que si vous ne définissez pas les encarts du haut et du bas, l'image finira par être déformée.
Julius
16

iOS 11 jette un problème dans bon nombre de ces solutions, je viens donc de résoudre mes problèmes sur iOS 11 en sous-classant UITabBar et en remplaçant layoutSubviews.

class MainTabBar: UITabBar {

    override func layoutSubviews() {
        super.layoutSubviews()

        // iOS 11: puts the titles to the right of image for horizontal size class regular. Only want offset when compact.
        // iOS 9 & 10: always puts titles under the image. Always want offset.
        var verticalOffset: CGFloat = 6.0

        if #available(iOS 11.0, *), traitCollection.horizontalSizeClass == .regular {
            verticalOffset = 0.0
        }

        let imageInset = UIEdgeInsets(
            top: verticalOffset,
            left: 0.0,
            bottom: -verticalOffset,
            right: 0.0
        )

        for tabBarItem in items ?? [] {
            tabBarItem.title = ""
            tabBarItem.imageInsets = imageInset
        }
    }
}
atlwx
la source
c'est la seule chose qui a fonctionné pour moi mais j'ai dû mettre le code dans 'override func viewDidLayoutSubviews' de la sous-classe de MyTabBarController. J'ai sous-classé le tabBarController et l'ai nommé ainsi
Lance Samaria
La solution a bien fonctionné pour moi. Je l'ai utilisé comme extension, donc c'est plus simple à ajouter
Michal Gumny
@LanceSamaria cela a fonctionné sans que je doive toucher le code du contrôleur de barre d'onglets
Pranav Kasetti
12

J'ai utilisé le code suivant dans le viewDidLoad de mon BaseTabBarController. Notez que dans mon exemple, j'ai 5 onglets, et l'image sélectionnée sera toujours base_image + "_selected".

// Get tab bar and set base styles
let tabBar = self.tabBar;
tabBar.backgroundColor = UIColor.whiteColor()

// Without this, images can extend off top of tab bar
tabBar.clipsToBounds = true

// For each tab item..
let tabBarItems = tabBar.items?.count ?? 0
for i in 0 ..< tabBarItems {
    let tabBarItem = tabBar.items?[i] as UITabBarItem

    // Adjust tab images (Like mstysf says, these values will vary)
    tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -6, 0);

    // Let's find and set the icon's default and selected states
    // (use your own image names here)
    var imageName = ""
    switch (i) {
    case 0: imageName = "tab_item_feature_1"
    case 1: imageName = "tab_item_feature_2"
    case 2: imageName = "tab_item_feature_3"
    case 3: imageName = "tab_item_feature_4"
    case 4: imageName = "tab_item_feature_5"
    default: break
    }
    tabBarItem.image = UIImage(named:imageName)!.imageWithRenderingMode(.AlwaysOriginal)
    tabBarItem.selectedImage = UIImage(named:imageName + "_selected")!.imageWithRenderingMode(.AlwaysOriginal)
}
Quatre
la source
1
Au lieu d'utiliser for var i = 0; i < tabBar... , vous auriez pu simplement dire; for tabBarItems in tabBar.items!
Jesse Onolemen
10

Approche Swift 4

J'ai pu faire l'astuce en implémentant une fonction qui prend un TabBarItem et le met en forme.

Déplace l'image un peu vers le bas pour la rendre plus centrée et masque également le texte de la barre d'onglets. Fonctionne mieux que de simplement définir son titre sur une chaîne vide, car lorsque vous avez également une barre de navigation, la barre de tabulation récupère le titre de la vueContrôleur lorsqu'il est sélectionné

func formatTabBarItem(tabBarItem: UITabBarItem){
    tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
    tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:UIColor.clear], for: .selected)
    tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:UIColor.clear], for: .normal)
}

Dernière syntaxe

extension UITabBarItem {
    func setImageOnly(){
        imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
        setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.clear], for: .selected)
        setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.clear], for: .normal)
    }
 }

Et utilisez-le simplement dans votre tabBar comme:

tabBarItem.setImageOnly()
José Tapizquent
la source
6

Voici une meilleure façon, plus infaillible de faire cela, autre que la réponse principale:

[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}
                                         forState:UIControlStateNormal];
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}
                                         forState:UIControlStateHighlighted];

Mettez-le dans votre AppDelegate.didFinishLaunchingWithOptionsafin qu'il affecte tous les boutons de la barre d'onglets tout au long de la vie de votre application.

Ézéchiel Victor
la source
3
Cela ne fait que masquer le titre et ne règle pas la position de l'image.
mustafa du
2
Ouais, mais la question ne dit rien sur le réglage de l'image. Cacher juste le texte. Et bien cacher le texte au détriment de la suppression du titre d'un contrôleur de vue semble faux. Surtout lorsque vous pourriez utiliser ce titre pour l'afficher dans le cadre de votre navigationviewcontroller
Dan1one
6

Une extension UITabBarController minimale et sûre dans Swift (basée sur la réponse @ korgx9):

extension UITabBarController {
  func removeTabbarItemsText() {
    tabBar.items?.forEach {
      $0.title = ""
      $0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
    }
  }
}
Federico Zanetello
la source
2

Basé sur la réponse de ddiego , dans Swift 4.2 :

extension UITabBarController {
    func cleanTitles() {
        guard let items = self.tabBar.items else {
            return
        }
        for item in items {
            item.title = ""
            item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
        }
    }
}

Et il vous suffit d'appeler self.tabBarController?.cleanTitles()votre contrôleur de vue.

j_gonfer
la source
1

Sur la base de toutes les bonnes réponses de cette page, j'ai conçu une autre solution qui vous permet également d'afficher à nouveau le titre. Au lieu de supprimer le contenu du titre, je change simplement la couleur de la police en transparent.

extension UITabBarItem {

    func setTitleColorFor(normalState: UIColor, selectedState: UIColor) {
        self.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: normalState], for: .normal)
        self.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: selectedState], for: .selected)
    }

}


extension UITabBarController {

    func hideItemsTitle() {

        guard let items = self.tabBar.items else {
            return
        }

        for item in items {
            item.setTitleColorFor(normalState: UIColor(white: 0, alpha: 0), selectedState: UIColor(white: 0, alpha: 0))
            item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
        }

    }

    func showItemsTitle() {

        guard let items = self.tabBar.items else {
            return
        }

        for item in items {
            item.setTitleColorFor(normalState: .black, selectedState: .yellow)
            item.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }

    }

}
ladislas
la source
0

entrez la description de l'image ici

code:

private func removeText() {
    if let items = yourTabBarVC?.tabBar.items {
       for item in items {
          item.title = ""
       }
    }
 }
Giang
la source
0

Le moyen le plus simple et fonctionne toujours:

class TabBar: UITabBar {

    override func layoutSubviews() {
        super.layoutSubviews()

        subviews.forEach { subview in
            if subview is UIControl {
                subview.subviews.forEach {
                    if $0 is UILabel {
                        $0.isHidden = true
                        subview.frame.origin.y = $0.frame.height / 2.0
                    }
                }
            }
        }
    }
}
JulianKro
la source
0

Dans mon cas, le même ViewController a été utilisé dans TabBar et d'autres flux de navigation. Dans mon ViewController, j'ai défini self.title = "Some Title"ce qui apparaissait dans TabBar quel que soit le titre du paramètrenil ou le vide lors de l'ajout dans la barre d'onglets. J'ai également défini imageInsetscomme suit:

item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)

Donc, dans mon ViewController, j'ai géré le titre de navigation comme suit:

if isFromTabBar {
   // Title for NavigationBar when ViewController is added in TabBar
   // NOTE: Do not set self.title = "Some Title" here as it will set title of tabBarItem
   self.navigationItem.title = "Some Title"
} else {
   // Title for NavigationBar when ViewController is opened from navigation flow
   self.title = "Some Title"
}
Chintan Shah
la source
0

créez une sous-classe de UITabBarController et affectez-la à votre tabBar, puis dans la méthode viewDidLoad, placez cette ligne de code:

tabBar.items?.forEach({ (item) in
        item.imageInsets = UIEdgeInsets.init(top: 8, left: 0, bottom: -8, right: 0)
    })
soheil pakgohar
la source
0

TabBar personnalisé - iOS 13, Swift 5, XCode 11

  • Éléments TabBar sans texte
  • Éléments TabBar centrés verticalement
  • Vue TabBar arrondie
  • TabBar Position et cadres dynamiques

Basé sur le storyboard. Il peut également être réalisé facilement par programme. Seulement 4 étapes à suivre:

  1. Les icônes de la barre d'onglets doivent être de 3 tailles, de couleur noire. Habituellement, je télécharge depuis fa2png.io - tailles: 25x25, 50x50, 75x75. Les fichiers image PDF ne fonctionnent pas!

    entrez la description de l'image ici

  2. Dans Storyboard pour l'élément de la barre d'onglets, définissez l'icône que vous souhaitez utiliser via l'inspecteur d'attributs. (voir capture d'écran)

entrez la description de l'image ici

  1. TabBarController personnalisé -> Nouveau fichier -> Type: UITabBarController -> Définir sur le storyboard. (voir capture d'écran)

entrez la description de l'image ici

  1. Classe UITabBarController

    classe RoundedTabBarViewController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view.
        // Custom tab bar view
        customizeTabBarView()
    }
    
    private func customizeTabBarView() {
        let tabBarHeight = tabBar.frame.size.height
        self.tabBar.layer.masksToBounds = true
        self.tabBar.isTranslucent = true
        self.tabBar.barStyle = .default
        self.tabBar.layer.cornerRadius = tabBarHeight/2
        self.tabBar.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let viewWidth = self.view.bounds.width
        let leadingTrailingSpace = viewWidth * 0.05
    
        tabBar.frame = CGRect(x: leadingTrailingSpace, y: 200, width: viewWidth - (2 * leadingTrailingSpace), height: 49)
    }

    }

  2. Résultat entrez la description de l'image ici

Doci
la source
0

Si vous cherchez à centrer les onglets / modifier les encarts d'image sans utiliser de nombres magiques, ce qui suit a fonctionné pour moi (dans Swift 5.2.2):

Dans une sous-classe UITabBarController , vous pouvez ajouter des incrustations d'image après avoir défini les contrôleurs de vue.

override var viewControllers: [UIViewController]? {
    didSet {
      addImageInsets()
    }
}

func addImageInsets() {
    let tabBarHeight = tabBar.frame.height

    for item in tabBar.items ?? [] where item.image != nil {
      let imageHeight = item.image?.size.height ?? 0
      let inset = CGFloat(Int((tabBarHeight - imageHeight) / 4))
      item.imageInsets = UIEdgeInsets(top: inset,
                                      left: 0,
                                      bottom: -inset,
                                      right: 0)
    }
}

Plusieurs des options ci-dessus répertorient les solutions permettant de masquer le texte.

Campbell_Souped
la source