Eliminar el texto del elemento de la barra de pestañas, mostrar solo la imagen

90

Pregunta simple, ¿cómo puedo eliminar el texto del elemento de la barra de pestañas y mostrar solo la imagen?

Quiero que me gusten los elementos de la barra en la aplicación de Instagram:

ingrese la descripción de la imagen aquí

En el inspector en xcode 6 elimino el título y elijo una imagen @ 2x (50px) y @ 3x (75px). Sin embargo, la imagen no utiliza el espacio libre del texto eliminado. ¿Alguna idea de cómo lograr la misma imagen de elemento de barra de pestañas como en la aplicación de Instagram?

Voto a favor
fuente
1
usando ""para el título, tal vez?
holex
1
Establecer compensaciones es solo un truco, la respuesta correcta está un poco más abajo. Debe usar navigationItem.title = "algún título"
Davit Siradeghyan

Respuestas:

129

Deberías jugar con la imageInsetspropiedad de UITabBarItem. Aquí hay un código de muestra:

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

Los valores internos UIEdgeInsetsdependen del tamaño de su imagen. Aquí está el resultado de ese código en mi aplicación:

ingrese la descripción de la imagen aquí

Mustafa
fuente
25
También puede ajustar las inserciones de la imagen en el inspector.
Upvote
Los números mágicos son una mala idea. Consulte mi respuesta para conocer una forma universalmente compatible de lograr lo mismo.
Ezekiel Victor
4
Esto ya no funciona en iOS 11; si hace doble clic en la pestaña activa, se duplicarán las inserciones por alguna razón.
Ben Gotow
@BenGotow mismo problema tienes alguna solución?
Dixit Akabari
@DixitAkabari otras personas ya han publicado algunas buenas soluciones para iOS 11
Pranav Kasetti
78
// 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
fuente
1
En lugar de eliminar el título, cambie el color del texto para borrarlo. El título puede resultar útil.
Eduardo Mauro
1
¡Kodos a Eduardo! Hizo que realiza una buena opción también para establecer un UIOffset vertical en titlePositionAjustement del artículo
Julius
2
¿Dónde pones esto en tu controlador TabBar personalizado?
UKDataGeek
69

Así es como se hace en un guión gráfico.

Borre el texto del título y configure la imagen insertada como en la captura de pantalla a continuación

ingrese la descripción de la imagen aquí

Recuerde que el tamaño del icono debe seguir las pautas de diseño de Apple.

ingrese la descripción de la imagen aquí

Esto significa que debe tener 25px x 25px para @ 1x, 50px x 50px para @ 2x, 75px x 75px para @ 3x

Nuynait
fuente
45

El uso del enfoque con la configuración de cada propiedad UITabBarItems titleen "" y la actualización imageInsetsno funcionará correctamente si self.titleestá configurado el controlador de vista . Por ejemplo, si self.viewControllersUITabBarController está incrustado UINavigationControllery necesita que el título se muestre en la barra de navegación. En este caso, configure UINavigationItemel título directamente usando self.navigationItem.title, no self.title.

Stefan
fuente
2
Este parece un método mucho más limpio. +1 @Oleg esto debe marcarse como la respuesta.
akseli
29

Versión rápida de ddiego answer

Compatible con iOS 11

Llame a esta función en viewDidLoad de cada primer hijo de viewControllers después de configurar el título de viewController

Mejores prácticas:

Alternativamente, como sugirió @daspianist en los comentarios

Haga una subclase como esta clase BaseTabBarController: UITabBarController, UITabBarControllerDelegate y coloque esta función en la subclase viewDidLoad

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
fuente
2
¡Gran función! Alternativamente, podría hacer una subclase como esta class BaseTabBarController: UITabBarController, UITabBarControllerDelegatey poner esta función en la subclaseviewDidLoad
daspianist
26

Si está utilizando guiones gráficos, esta sería su mejor opción. Recorre todos los elementos de la barra de pestañas y, para cada uno, establece el título en nada y hace que la imagen aparezca en pantalla completa. (Debes haber agregado una imagen en el guión gráfico)

for tabBarItem in tabBar.items!
{
   tabBarItem.title = ""
   tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}
Marcos Reboucas
fuente
Es bueno tener en cuenta que si no configura las inserciones superior e inferior, la imagen terminará deformada.
Julius
16

iOS 11 daña muchas de estas soluciones, así que solucioné mis problemas en iOS 11 subclasificando UITabBar y anulando 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
fuente
esto es lo único que funcionó para mí, pero tuve que poner el código dentro de 'override func viewDidLayoutSubviews' de la subclase de MyTabBarController. Subclasé el tabBarController y lo nombré así
Lance Samaria
La solución funcionó para mí, muy bien. Lo usé como extensión para que sea más fácil de agregar
Michal Gumny
@LanceSamaria esto funcionó sin que yo tuviera que tocar el código del controlador de la barra de pestañas
Pranav Kasetti
12

Usé el siguiente código en viewDidLoad de mi BaseTabBarController. Tenga en cuenta que en mi ejemplo, tengo 5 pestañas y la imagen seleccionada siempre será 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)
}
Cuatro
fuente
1
En lugar de usar for var i = 0; i < tabBar... , podría haber dicho; for tabBarItems in tabBar.items!
Jesse Onolemen
10

Enfoque Swift 4

Pude hacer el truco implementando una función que toma un TabBarItem y le da formato.

Mueve la imagen un poco hacia abajo para que esté más centrada y también oculta el texto de la barra de pestañas. Funcionó mejor que simplemente establecer su título en una cadena vacía, porque cuando también tiene una NavigationBar, TabBar recupera el título del viewController cuando se selecciona

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)
}

Última sintaxis

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)
    }
 }

Y utilícelo en su tabBar como:

tabBarItem.setImageOnly()
José Tapizquent
fuente
6

Aquí hay una forma mejor y más infalible de hacer esto que no sea la respuesta principal:

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

Pon esto en tu AppDelegate.didFinishLaunchingWithOptionspara que afecte a todos los botones de la barra de pestañas a lo largo de la vida de tu aplicación.

Ezequiel Víctor
fuente
3
Esto solo oculta el título y no ajusta la posición de la imagen.
Mustafa
2
Sí, pero la pregunta no decía nada sobre el ajuste de la imagen. Solo esconde el texto. Y ocultar el texto en detrimento de eliminar el título de un controlador de vista parece incorrecto. Especialmente cuando podría usar ese título para mostrarlo como parte de su
controlador de vista de
6

Una extensión UITabBarController mínima y segura en Swift (basada en la respuesta de @ korgx9):

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

Basado en la respuesta de ddiego , en 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)
        }
    }
}

Y solo necesita llamar self.tabBarController?.cleanTitles()a su controlador de vista.

j_gonfer
fuente
1

Basado en todas las excelentes respuestas en esta página, he creado otra solución que también le permite mostrar el título nuevamente. En lugar de eliminar el contenido del título, simplemente cambio el color de la fuente a transparente.

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
fuente
0

ingrese la descripción de la imagen aquí

código:

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

La forma más fácil y siempre funciona:

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
fuente
0

En mi caso, se usó el mismo ViewController en TabBar y otro flujo de navegación. Dentro de mi ViewController, configuré lo self.title = "Some Title"que aparecía en TabBar independientemente del título de configuración nilo en blanco al agregarlo en la barra de pestañas. También he establecido imageInsetslo siguiente:

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

Entonces, dentro de mi ViewController, he manejado el título de navegación de la siguiente manera:

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
fuente
0

haga una subclase de UITabBarController y asígnela a su tabBar, luego en el método viewDidLoad coloque esta línea de código:

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

TabBar personalizado - iOS 13, Swift 5, XCode 11

  • Elementos de TabBar sin texto
  • Elementos de TabBar centrados verticalmente
  • Vista de barra de pestañas redondeada
  • TabBar Dynamic posición y marcos

Basado en guiones gráficos. También se puede lograr fácilmente mediante programación. Solo 4 pasos a seguir:

  1. Los iconos de la barra de pestañas deben tener 3 tamaños, en color negro. Normalmente, descargo de fa2png.io - tamaños: 25x25, 50x50, 75x75. ¡Los archivos de imagen PDF no funcionan!

    ingrese la descripción de la imagen aquí

  2. En Storyboard, para el elemento de la barra de pestañas, establezca el icono que desea usar a través del Inspector de atributos. (ver captura de pantalla)

ingrese la descripción de la imagen aquí

  1. TabBarController personalizado -> Nuevo archivo -> Tipo: UITabBarController -> Establecer en el guión gráfico. (ver captura de pantalla)

ingrese la descripción de la imagen aquí

  1. Clase UITabBarController

    class 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. Resultado ingrese la descripción de la imagen aquí

Doci
fuente
0

Si está buscando centrar las pestañas / cambiar las inserciones de la imagen sin usar números mágicos, lo siguiente me ha funcionado (en Swift 5.2.2):

En una subclase UITabBarController , puede agregar agregar las inserciones de imagen después de configurar los controladores de vista.

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)
    }
}

Varias de las opciones anteriores enumeran soluciones para tratar de ocultar el texto.

Campbell_Souped
fuente