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:
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?
ios
swift
uitabbaritem
Voto a favor
fuente
fuente
""
para el título, tal vez?Respuestas:
Deberías jugar con la
imageInsets
propiedad deUITabBarItem
. 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
UIEdgeInsets
dependen del tamaño de su imagen. Aquí está el resultado de ese código en mi aplicación:fuente
// 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); }
fuente
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
Recuerde que el tamaño del icono debe seguir las pautas de diseño de Apple.
Esto significa que debe tener 25px x 25px para @ 1x, 50px x 50px para @ 2x, 75px x 75px para @ 3x
fuente
El uso del enfoque con la configuración de cada propiedad
UITabBarItem
stitle
en""
y la actualizaciónimageInsets
no funcionará correctamente siself.title
está configurado el controlador de vista . Por ejemplo, siself.viewControllers
UITabBarController está incrustadoUINavigationController
y necesita que el título se muestre en la barra de navegación. En este caso, configureUINavigationItem
el título directamente usandoself.navigationItem.title
, noself.title
.fuente
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
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) } } }
fuente
class BaseTabBarController: UITabBarController, UITabBarControllerDelegate
y poner esta función en la subclaseviewDidLoad
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) }
fuente
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 } } }
fuente
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) }
fuente
for var i = 0; i < tabBar...
, podría haber dicho;for tabBarItems in tabBar.items!
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:
fuente
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.didFinishLaunchingWithOptions
para que afecte a todos los botones de la barra de pestañas a lo largo de la vida de tu aplicación.fuente
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) } } }
fuente
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.fuente
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) } } }
fuente
código:
private func removeText() { if let items = yourTabBarVC?.tabBar.items { for item in items { item.title = "" } } }
fuente
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 } } } } } }
fuente
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ónnil
o en blanco al agregarlo en la barra de pestañas. También he establecidoimageInsets
lo 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" }
fuente
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) })
fuente
TabBar personalizado - iOS 13, Swift 5, XCode 11
Basado en guiones gráficos. También se puede lograr fácilmente mediante programación. Solo 4 pasos a seguir:
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!
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)
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) }
}
Resultado
fuente
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.
fuente