ios - item - tab bar swift 4 programmatically
Eliminar el texto del elemento de la barra de pestaƱas, mostrar solo la imagen (12)
Pregunta simple, ¿cómo puedo eliminar el texto del elemento de la barra de pestañas y mostrar solo la imagen?
Quiero que los elementos del bar me gusten en la aplicación de instagram:
En el inspector en xcode 6 elimino el título y elijo una imagen @ 2x (50px) y una @ 3x (75px). Sin embargo, la imagen no usa el espacio libre del texto eliminado. ¿Alguna idea de cómo lograr la misma imagen de elemento de la barra de pestañas como en la aplicación Instagram?
Aquí hay una forma mejor y más infalible para 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 durante toda la vida de tu aplicación.
Así es como lo haces en un guión gráfico.
Borre el texto del título y configure la inserción de la imagen como en la captura de pantalla siguiente
Recuerde que el tamaño del icono debe seguir la pauta 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
Debería jugar con la propiedad UITabBarItem
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 dentro de UIEdgeInsets
dependen del tamaño de su imagen. Aquí está el resultado de ese código en mi aplicación:
Enfoque Swift 4
Pude hacer el truco al implementar una función que toma un TabBarItem y le da formateo.
Mueve la imagen un poco hacia abajo para que quede 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 barra de navegación, el TabBar recupera el título de 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)
}
Si estás usando storyboards, esta sería tu 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 se muestre a pantalla completa. (Debe haber agregado una imagen en el guión gráfico)
for tabBarItem in tabBar.items!
{
tabBarItem.title = ""
tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}
Una extensión mínima y segura de UITabBarController en Swift (basada en @ korgx9 answer):
extension UITabBarController {
func removeTabbarItemsText() {
tabBar.items?.forEach {
$0.title = ""
$0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
}
}
}
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)
}
Usar el enfoque con establecer la propiedad del title
cada UITabBarItem
en ""
y actualizar imageInsets
no funcionará correctamente si está configurado el controlador self.title
. Por ejemplo, si self.viewControllers
de UITabBarController están incrustados en UINavigationController
y necesita el título para mostrarse en la barra de navegación. En este caso, establezca el título de self.navigationItem.title
directamente utilizando self.navigationItem.title
, no self.title
.
iOS 11 presenta un inconveniente en muchas de estas soluciones, así que solo solucioné mis problemas en iOS 11 al crear una subclase de UITabBar y reemplazar las vistas de diseño.
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
}
}
}
Versión rápida de la respuesta ddiego
Llame a esta función en viewDidLoad de cada primer hijo de viewControllers después de configurar el título de viewController
func removeTabbarItemsText() {
if let items = tabBar.items {
for item in items {
item.title = ""
item.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0);
}
}
}
// 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);
}