ios 11 UITabBar UITabBarItem problema de posicionamiento


He creado mi aplicación usando el nuevo Xcode 9 beta para ios 11. He encontrado un problema con UITabBar donde los elementos se extienden a través de la UITabBar y el título está alineado a la derecha de la imagen. He intentado cambiar el código para que funcione, pero todavía no tiene éxito.

Ios 10 +

introduzca la descripción de la imagen aquí

Ios 11

introduzca la descripción de la imagen aquí

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

Author: Keyur, 2017-06-29

6 answers

Estoy manteniendo una gran aplicación para iPad escrita principalmente en Objective-C que ha sobrevivido a varias versiones de iOS. Me encontré con la situación en la que necesitaba la apariencia de la barra de pestañas pre-iOS 11 (con los iconos 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 anula el método traitCollection para que siempre devuelva una colección de rasgos compacta horizontalmente. Esto hace que iOS 11 muestre los títulos debajo de los iconos para toda la barra de pestañas botón.

Para usar esto, establezca la clase personalizada de las barras de pestañas en el guion gráfico a esta nueva subclase y cambie cualquier salida en el código que apunte a las barras de pestañas para que sean de este nuevo tipo (no olvide importar el archivo de encabezado a continuación).

El.el archivo h está bastante 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
 33
Author: John C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-29 18:23:41

Basado en la respuesta de John C, aquí está la versión de Swift 3 que se puede usar programáticamente sin necesidad de guion gráfico o subclase:

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
    }
}
 24
Author: massimobio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-21 16:21:29

Para evitar estropear cualquier otro rasgo no es mejor combinar con las superclases:

- (UITraitCollection *)traitCollection
{
  UITraitCollection *curr = [super traitCollection];
  UITraitCollection *compact = [UITraitCollection  traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];

  return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
 15
Author: Andy C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 09:30:35

NOTA: Esta correcció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 conversación de WWDC , este es el nuevo comportamiento para:

  • iPhone en 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 horizontal como en iPad, donde mostramos el icono y el texto uno al lado del otro. Y en particular en 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.

 12
Author: Dan Rosenstark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-22 18:42:39

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 utiliza 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:

introduzca la descripción de la imagen aquí

 5
Author: Max Desiatov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-22 11:31:01

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 el diseño centrado 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
 2
Author: twofish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-12 12:42:05