webentwicklung-frage-antwort-db.com.de

ios 11 UITabBar UITabBarItem-Positionierungsproblem

Ich habe meine App mit der neuen Xcode 9-Betaversion für ios 11 erstellt. Ich habe ein Problem mit UITabBar gefunden, bei dem Elemente über die UITabBar verteilt werden und der Titel direkt am Bild ausgerichtet ist. Ich habe versucht, den Code zu ändern, damit er funktioniert, aber immer noch nicht erfolgreich.

iOS 10+

enter image description here

ios 11

enter image description here

Ich könnte die Position des Titels mit tabBarItem.titlePositionAdjustment Ändern, aber das ist nicht meine Voraussetzung, da es automatisch unter dem Bild selbst erscheinen sollte. Ich habe versucht, tabbar.itemPositioning to UITabBarItemPositioningCentered Zu setzen und auch versucht, itemSpacing und width zu ändern, aber immer noch nicht funktioniert. Kann mir jemand helfen zu verstehen, warum dies passiert und wie dies behoben werden kann? Ich möchte, dass es die ios 10+ Version mag und Bilder von der linken Ecke eines iPad aufgenommen werden.

44
Gihan

Ich verwalte eine große iPad-App, die hauptsächlich in Objective-C geschrieben ist und mehrere iOS-Versionen überstanden hat. Ich sah mich mit der Situation konfrontiert, dass ich für einige Registerkarten das Erscheinungsbild der Registerkartenleiste vor iOS 11 (mit den Symbolen über den Titeln anstatt neben ihnen) benötigte. Meine Lösung bestand darin, eine Unterklasse von UITabBar zu erstellen, die die traitCollection -Methode überschreibt, sodass immer eine horizontal kompakte Merkmalauflistung zurückgegeben wird. Dies bewirkt, dass iOS 11 die Titel unter den Symbolen für alle Schaltflächen der Registerkartenleiste anzeigt.

Um dies zu verwenden, setzen Sie die benutzerdefinierte Klasse der Registerkartenleisten im Storyboard auf diese neue Unterklasse und ändern Sie alle Ausgänge im Code, die auf die Registerkartenleisten dieses neuen Typs verweisen (vergessen Sie nicht, die Headerdatei zu importieren unten).

Die .h-Datei ist in diesem Fall ziemlich leer:

//
//  MyTabBar.h
//

#import <UIKit/UIKit.h>

@interface MyTabBar : UITabBar

@end

Hier ist die .m-Datei mit der Implementierung der traitCollection -Methode:

//
//  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
38
John C.

Basierend auf der Antwort von John C ist hier die Version Swift 3), die programmgesteuert ohne Storyboard oder Unterklassen verwendet werden kann:

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
    }
}
33
massimobio

Um andere Eigenschaften nicht zu verfälschen, ist es nicht besser, sie mit den Superklassen zu kombinieren:

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

  return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
18
Andy C

HINWEIS: Dieser Fix oben scheint recht gut zu funktionieren. Ich bin mir nicht sicher, wie es in Zukunft funktionieren wird, aber im Moment funktioniert es ganz gut.


Laut diesem WWDC-Vortrag ist dies das neue Verhalten für:

  • iPhone in Landschaft
  • iPad die ganze Zeit

Und wenn ich richtig lese, kann dieses Verhalten nicht geändert werden:

Wir haben dieses brandneue Erscheinungsbild für die Registerkartenleiste, sowohl im Querformat als auch auf dem iPad, bei dem das Symbol und der Text nebeneinander angezeigt werden. Insbesondere bei iPhones ist das Symbol kleiner und die Registerkartenleiste kleiner, um vertikal etwas mehr Platz zu schaffen.

14
Dan Rosenstark

Swift 4-Version mit einer Unterklasse, die Kollisionen bei der Benennung von Erweiterungen/Kategorien vermeidet:

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

    return UITraitCollection(horizontalSizeClass: .compact)
  }
}

Wenn Sie Interface Builder und Storyboards verwenden, können Sie die Registerkartenleistenansicht in Ihrer UITabBarController Szene auswählen und ihre Klasse im Identitätsinspektor in TabBar ändern:

enter image description here

10
Max Desiatov

Zusätzlich zu Johns Antwort:

Wenn Sie mehr als 4 Registerkartenelemente haben und die Schaltfläche "Mehr" nicht verwenden möchten, müssen Sie eine andere Größenklasse verwenden. Und wenn Sie das ursprünglich zentrierte Layout der Elemente verwenden möchten, müssen Sie eine andere Methode wie die folgende hinzufügen:

#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
twofish