ios objective-c uitabbar uitabbaritem ios11

ios 11 Problema de posicionamiento UITabBar UITabBarItem



objective-c ios11 (6)

He creado mi aplicación utilizando la nueva Xcode 9 beta para iOS 11. He encontrado un problema con UITabBar donde los artículos se extienden a través de la UITabBar y el título está alineado correctamente con la imagen. He intentado cambiar el código para que funcione, pero todavía no es exitoso.

ios 10+

ios 11

Podría cambiar la posición del título usando tabBarItem.titlePositionAdjustment Pero ese no es mi requisito, ya que debería aparecer automáticamente debajo de la imagen. Intenté establecer tabbar.itemPositioning to UITabBarItemPositioningCentered y también intenté cambiar itemSpacing y width , pero aún no funcionó. ¿Alguien puede ayudarme a entender por qué sucede esto y cómo solucionarlo? Quiero que me guste la versión de iOS 10+ y las imágenes se toman desde la esquina más a la izquierda de un iPad.


Además de la respuesta de Juan:

Si tiene más de 4 elementos de la barra de pestañas y no desea el botón "Más", debe tomar una clase de tamaño diferente. Y si desea la distribución centrada original de los elementos, debe agregar otro método como este:

#import "PreIOS11TabBarController.h" @interface PreIOS11TabBarController () @end @implementation PreIOS11TabBarController // In iOS 11, UITabBarItem''s have the title to the right of the icon in horizontally regular environments // (i.e. the iPad). In order to keep the title below the icon, it was necessary to subclass UITabBar and override // traitCollection to make it horizontally compact. - (UITraitCollection *)traitCollection { return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified]; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; self.tabBar.itemPositioning = UITabBarItemPositioningCentered; } @end


Estoy manteniendo una gran aplicación para iPad escrita principalmente en Objective-C que ha sobrevivido a varios lanzamientos de iOS. Me encontré con la situación en la que necesitaba la apariencia de barra de pestañas anterior a iOS 11 (con los íconos encima de los títulos en lugar de al lado de ellos) para un par de barras de pestañas. Mi solución fue crear una subclase de UITabBar que anule el método traitCollection para que siempre devuelva una colección de rasgos compactos horizontalmente. Esto hace que iOS 11 muestre los títulos debajo de los iconos de todos los botones de la barra de pestañas.

Para usar esto, establezca la clase personalizada de las barras de tabulación en el guión gráfico a esta nueva subclase y cambie las salidas en el código que apuntan a que las barras de tabulación deben ser de este tipo nuevo (no olvide importar el archivo de encabezado). abajo).

El archivo .h está prácticamente vacío en este caso:

// // MyTabBar.h // #import <UIKit/UIKit.h> @interface MyTabBar : UITabBar @end

Aquí está el archivo .m con la implementación del método traitCollection :

// // MyTabBar.m // #import "MyTabBar.h" @implementation MyTabBar // In iOS 11, UITabBarItem''s have the title to the right of the icon in horizontally regular environments // (i.e. the iPad). In order to keep the title below the icon, it was necessary to subclass UITabBar and override // traitCollection to make it horizontally compact. - (UITraitCollection *)traitCollection { return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]; } @end


Para evitar ensuciar cualquier otro rasgo, no es mejor combinarlo con las superclases:

- (UITraitCollection *)traitCollection { UITraitCollection *curr = [super traitCollection]; UITraitCollection *compact = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]; return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]]; }


Según la respuesta de John C, aquí está la versión de Swift 3 que se puede utilizar mediante programación sin necesidad de guiones gráficos o subclases:

extension UITabBar { // Workaround for iOS 11''s new UITabBar behavior where on iPad, the UITabBar inside // the Master view controller shows the UITabBarItem icon next to the text override open var traitCollection: UITraitCollection { if UIDevice.current.userInterfaceIdiom == .pad { return UITraitCollection(horizontalSizeClass: .compact) } return super.traitCollection } }


Versión Swift 4 con una subclase que evita la colisión de nombres de extensión / categoría:

class TabBar: UITabBar { override var traitCollection: UITraitCollection { guard UIDevice.current.userInterfaceIdiom == .pad else { return super.traitCollection } return UITraitCollection(horizontalSizeClass: .compact) } }

Si usa Interface Builder, puede seleccionar la vista de la barra de pestañas en su escena UITabBarController y cambiar su clase a TabBar en el Inspector de identidad:


NOTA: Esta solución anterior parece funcionar bastante bien. No estoy seguro de cómo funcionará en el futuro, pero por ahora está funcionando bastante bien.

De acuerdo con esta charla de la WWDC , este es el nuevo comportamiento para:

  • iPhone en el paisaje
  • iPad todo el tiempo

Y si estoy leyendo correctamente, este comportamiento no se puede cambiar:

Tenemos esta nueva apariencia para la barra de pestañas, tanto en paisaje como en iPad, donde mostramos el icono y el texto uno al lado del otro. Y, en particular en los iPhones, el icono es más pequeño y la barra de pestañas es más pequeña para dar un poco más de espacio verticalmente.