iOS 11 iPhone X Simulator UITabBar-Symbole und -Titel werden übereinander gerendert


134

Hat jemand ein Problem mit dem iPhone X-Simulator rund um die UITabBar-Komponente?

Meins scheint die Symbole und den Titel übereinander zu rendern. Ich bin mir nicht sicher, ob mir etwas fehlt. Ich habe es auch im iPhone 8-Simulator ausgeführt und auf einem tatsächlichen Gerät, auf dem es gut aussieht, wie auf dem abgebildet Storyboard.

iPhone X:

iPhone X UITabBar Fehler

iPhone 8

iPhone 8 UITabBar funktioniert


1
Mein ähnliches Problem: Die Auswahlanzeige Bildansicht sinkt in der TabBar-Ansicht etwa 16 Punkte in iPhone X.
Itachi

Zu Ihrer
Information

Dies ist ein UIKIT-Fehler, der immer noch besteht. Einschränkungen müssen genau richtig eingerichtet werden. Siehe meine Antwort unten!
RyanM

Ich hatte solche
Maxime Ashurov

Antworten:


40

Ich konnte das Problem umgehen, indem ich einfach invalidateIntrinsicContentSize in der UITabBar in viewDidLayoutSubviews aufrief.

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self.tabBar invalidateIntrinsicContentSize];
}

Hinweis: Der untere Rand der Registerkartenleiste muss sich im unteren Bereich der Hauptansicht befinden und nicht im sicheren Bereich. Die Registerkartenleiste sollte keine Höhenbeschränkung aufweisen.


Ich habe eine Registerkartenleiste ohne Höhenbeschränkung, die auf das Handbuch für das untere Layout beschränkt ist, und dies hat bei mir nicht funktioniert. Irgendwelche anderen Ideen?
Kenny Wyland

1
Funktioniert nicht, wenn homeVC VC A präsentiert, dann A entlässt und VC B von homeVC drückt. Dies ist eine Abhilfe stackoverflow.com/a/47225653/1553324
ooops

1
Das Hinzufügen dieser Methode in Kombination mit dem Fixieren der Registerkartenleiste am unteren Rand der Übersicht ( nicht des sicheren Bereichs) hat bei mir funktioniert.
Drew C

3
Ich musste auch hinzufügen [self.view layoutIfNeeded].
Iulian Onofrei

1
Dies funktioniert, aber ich habe gelernt, dass ich auch auf die Größe der Bilder in den Schaltflächen der Registerkartenleiste achten muss . Im Querformat (auf kompakten Geräten, jedoch nicht auf iPad- und iPhone Plus-Modellen) verwendet das System eine kompakte Registerkartenleiste, die kleinere Bilder enthalten soll, die Sie mit der landscapeImageEigenschaft der Schaltfläche in der Registerkartenleiste festlegen können . Empfohlene Größen finden Sie in [Apple HIG's] ( developer.apple.com/design/human-interface-guidelines/ios/… ) unter Benutzerdefinierte
Symbolgröße

25

Die von VoidLess bereitgestellte Antwort behebt TabBar-Probleme nur teilweise. Es behebt Layoutprobleme in der Registerkartenleiste. Wenn Sie jedoch einen Ansichtscontroller verwenden, der die Registerkartenleiste ausblendet, wird die Registerkartenleiste während der Animationen falsch gerendert (um sie zu reproduzieren, sollten Sie 2 Segmente haben - einen modalen und einen Push. Wenn Sie die Segmente abwechseln, können Sie dies tun siehe, dass die Tab-Leiste nicht richtig gerendert wird). Der folgende Code behebt beide Probleme. Gute Arbeit Apfel.

class SafeAreaFixTabBar: UITabBar {

var oldSafeAreaInsets = UIEdgeInsets.zero

@available(iOS 11.0, *)
override func safeAreaInsetsDidChange() {
    super.safeAreaInsetsDidChange()

    if oldSafeAreaInsets != safeAreaInsets {
        oldSafeAreaInsets = safeAreaInsets

        invalidateIntrinsicContentSize()
        superview?.setNeedsLayout()
        superview?.layoutSubviews()
    }
}

override func sizeThatFits(_ size: CGSize) -> CGSize {
    var size = super.sizeThatFits(size)
    if #available(iOS 11.0, *) {
        let bottomInset = safeAreaInsets.bottom
        if bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90) {
            size.height += bottomInset
        }
    }
    return size
}

override var frame: CGRect {
    get {
        return super.frame
    }
    set {
        var tmp = newValue
        if let superview = superview, tmp.maxY != 
        superview.frame.height {
            tmp.origin.y = superview.frame.height - tmp.height
        }

        super.frame = tmp
        }
    }
}

Ziel-C-Code:

@implementation VSTabBarFix {
    UIEdgeInsets oldSafeAreaInsets;
}


- (void)awakeFromNib {
    [super awakeFromNib];

    oldSafeAreaInsets = UIEdgeInsetsZero;
}


- (void)safeAreaInsetsDidChange {
    [super safeAreaInsetsDidChange];

    if (!UIEdgeInsetsEqualToEdgeInsets(oldSafeAreaInsets, self.safeAreaInsets)) {
        [self invalidateIntrinsicContentSize];

        if (self.superview) {
            [self.superview setNeedsLayout];
            [self.superview layoutSubviews];
        }
    }
}

- (CGSize)sizeThatFits:(CGSize)size {
    size = [super sizeThatFits:size];

    if (@available(iOS 11.0, *)) {
        float bottomInset = self.safeAreaInsets.bottom;
        if (bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90)) {
            size.height += bottomInset;
        }
    }

    return size;
}


- (void)setFrame:(CGRect)frame {
    if (self.superview) {
        if (frame.origin.y + frame.size.height != self.superview.frame.size.height) {
            frame.origin.y = self.superview.frame.size.height - frame.size.height;
        }
    }
    [super setFrame:frame];
}


@end

Komplette Lösung. Vielen Dank.
Sayalee Pote

4
Vielen Dank für Ihre Antwort. Aber wie verwendet man es in einer UITabBarController-Klasse?
Jojo

2
@Jojo, angesichts der Menge an Code, die zum Auffüllen der Registerkarten über Code benötigt wird, erstelle ich uitabbarcontroller immer mithilfe von Storyboards. Dort können Sie eine benutzerdefinierte Klasse für die Registerkartenleiste zuweisen. Hoffe das hilft.
Raimundas Sakalauskas

Dieses Problem tritt nicht auf einem realen Gerät auf. Ich habe es auf dem iPhone 11 Pro iOS 13
Akshay Jadhav

22

Es gibt einen Trick, mit dem wir das Problem lösen können.

Legen Sie einfach Ihre UITabBar in eine UIView.

Das funktioniert wirklich für mich.

Oder folgen Sie diesem Link für weitere Details.


3
Dies hat gut funktioniert, haben Sie eine Ansicht, die einfach die UITabBar enthält. Platzieren Sie die Beschränkungen in den sicheren Bereichen des UIView (L, R und Bottom), geben Sie ihm eine Höhe (49) und beschränken Sie die UITabBar auf allen Seiten auf das UIView.
SDsykes

1
Diese Lösung hat bei mir funktioniert. Ich habe keinen UITabController verwendet, nur UITabBar.
Riccardo Tesio

1
Hat für mich gearbeitet. Vielen Dank
Francis Lanthier

1
Das hat mir geholfen! Danke dir!
Glenn

2
Dies funktioniert, aber dann hat der "unsichere" Bereich möglicherweise nicht die gleiche Farbe wie die Registerkartenleiste (falls die Superansicht und die Registerkartenleiste nicht dieselbe Farbe haben)
iDev

16

überschreiben UITabBar sizeThatFits(_)für safeArea

extension UITabBar {
    static let height: CGFloat = 49.0

    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        guard let window = UIApplication.shared.keyWindow else {
            return super.sizeThatFits(size)
        }
        var sizeThatFits = super.sizeThatFits(size)
        if #available(iOS 11.0, *) {
            sizeThatFits.height = UITabBar.height + window.safeAreaInsets.bottom
        } else {
            sizeThatFits.height = UITabBar.height
        }
        return sizeThatFits
    }
}

Brillant. Ich habe gerade die benutzerdefinierte Größe meiner Registerkarte festgelegt und mich gefragt, warum dies auf dem iPhoneX nicht funktioniert. Andere Lösungen funktionieren bei mir nicht, da ich Tab Bar Controller verwende und keine Einschränkungen enthält.
Jindřich Rohlík

12

Ich habe dies zu viewWillAppearmeinem Brauch hinzugefügt UITabBarController, da keine der bereitgestellten Antworten für mich funktioniert hat:

tabBar.invalidateIntrinsicContentSize()
tabBar.superview?.setNeedsLayout()
tabBar.superview?.layoutSubviews()

1
Dies hat mir geholfen, ein Problem zu beheben, das mit dem Verschieben der TabBar an den oberen Bildschirmrand zusammenhängt. Danke dir!
Jay

Aber nicht für mich :(
Nick

9

Ich hatte das gleiche Problem.

Geben Sie hier die Bildbeschreibung ein

Wenn ich eine Konstante ungleich Null für die untere Einschränkung der UITabBar auf den sicheren Bereich setze:

Geben Sie hier die Bildbeschreibung ein

Es beginnt wie erwartet zu funktionieren ...

Geben Sie hier die Bildbeschreibung ein

Das ist die einzige Änderung, die ich vorgenommen habe, und ich habe keine Ahnung, warum es funktioniert, aber wenn jemand es tut, würde ich es gerne wissen.


1
Das habe ich am Ende getan, um es zum Laufen zu bringen, aber ja, ich habe keine Ahnung warum oder verstehe, was es tut. Für mich fühlt es sich immer noch wie ein
Käfer an

7

Das Verschieben der Registerkartenleiste um 1 Punkt von unten hat bei mir funktioniert.

Natürlich erhalten Sie dadurch eine Lücke, die Sie auf irgendeine Weise füllen müssen, aber der Text / die Symbole sind jetzt richtig positioniert.


7

Aha! Es ist tatsächlich Magie!

Ich habe das endlich herausgefunden, nachdem ich stundenlang Apple verflucht hatte.

UIKit erledigt dies tatsächlich für Sie und es scheint, dass die verschobenen Registerkartenleistenelemente auf eine falsche Einrichtung zurückzuführen sind (und wahrscheinlich auf einen tatsächlichen UIKit-Fehler). Es ist keine Unterklasse oder Hintergrundansicht erforderlich.

UITabBar funktioniert "nur", wenn es auf den unteren Bereich der Übersicht beschränkt ist, NICHT auf den unteren sicheren Bereich .

Es funktioniert sogar im Interface Builder.

Richtiges Setup

Arbeiten in IB

  1. Ziehen Sie im Interface Builder, der als iPhone X angezeigt wird, eine UITabBar an die Stelle, an der sie im unteren Bereich des sicheren Bereichs einrastet. Wenn Sie es fallen lassen, sollte es korrekt aussehen (füllen Sie den Raum bis zum unteren Rand aus).
  2. Sie können dann "Fehlende Einschränkungen hinzufügen" ausführen und IB fügt die richtigen Einschränkungen hinzu und Ihre Registerkartenleiste funktioniert auf magische Weise auf allen iPhones! (Beachten Sie, dass die untere Einschränkung einen konstanten Wert aufweist, der der Höhe des unsicheren Bereichs des iPhone X entspricht, die Konstante jedoch tatsächlich 0 ist.)

Manchmal funktioniert es immer noch nicht

In IB gebrochen

Was wirklich dumm ist, ist, dass Sie den Fehler auch in IB tatsächlich sehen können, selbst wenn Sie die genauen Einschränkungen hinzufügen, die IB in den obigen Schritten hinzufügt!

  1. Ziehen Sie eine UITabBar heraus und rasten Sie sie nicht in den unteren Sicherheitsbereich ein
  2. Hinzufügen von führenden, nachfolgenden und unteren Einschränkungen zur Übersicht (nicht sicherer Bereich) Seltsamerweise behebt sich dies von selbst, wenn Sie im Einschränkungsinspektor für die untere Einschränkung ein "Erstes und zweites Element umkehren" ausführen. ¯_ (ツ) _ / ¯

änderte alle Einschränkungen von sicherem Bereich zu Übersicht und arbeitete. Legende Ryan
RyanTCB

6

Behoben durch die Verwendung von UITabBar in Unterklassen zum Anwenden von safeAreaInsets:

class SafeAreaFixTabBar: UITabBar {

    var oldSafeAreaInsets = UIEdgeInsets.zero

    @available(iOS 11.0, *)
    override func safeAreaInsetsDidChange() {
        super.safeAreaInsetsDidChange()

        if oldSafeAreaInsets != safeAreaInsets {
            oldSafeAreaInsets = safeAreaInsets

            invalidateIntrinsicContentSize()
            superview?.setNeedsLayout()
            superview?.layoutSubviews()
        }
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var size = super.sizeThatFits(size)
        if #available(iOS 11.0, *) {
            let bottomInset = safeAreaInsets.bottom
            if bottomInset > 0 && size.height < 50 {
                size.height += bottomInset
            }
        }
        return size
    }
}

Löst einen Teil der Probleme, aber nicht alle. Bitte sehen Sie die vollständige Antwort unten
Raimundas Sakalauskas

Es hat bei mir funktioniert, wenn ich versuche, VCA zu präsentieren, dann VCA zu entlassen und VCB zu drücken.
Tai Le

Dies funktioniert für mich, aber ich muss die unterste Einschränkung auf die Übersicht und nicht auf den sicheren Bereich legen.
Yajra

Was mache ich mit dieser neuen Klasse, nachdem ich sie erstellt habe? Ich habe versucht, in meiner Anwendung nach UITabBar zu suchen und diese durch SafeAreaFixTabBar zu ersetzen. Ich habe folgende Vorkommen gefunden: func application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {SafeAreaFixTabB () .barTintColor = ... SafeAreaFixTabBar.appearance (). backgroundColor = ... SafeAreaFixTabBar.appearance (). tintColor = ... Aber nichts
behoben

4

Für mich gelöst, indem ich anrufe, [tabController.view setNeedsLayout];nachdem ich das Modal im Abschlussblock entlassen habe.

[vc dismissViewControllerAnimated:YES completion:^(){ 
     UITabBarController* tabController = [UIApplication sharedApplication].delegate.window.rootViewController;
     [tabController.view setNeedsLayout];
}];

2

Die UITabBar wird immer höher, um über der Home-Schaltfläche / Linie zu liegen. Sie zeichnet jedoch die Unteransicht an ihrer ursprünglichen Position und überlagert das UITabBarItem mit der Unteransicht.

Um dieses Problem zu umgehen, können Sie das iPhone X erkennen und dann die Höhe der Ansicht um 32 Pixel verkleinern, um sicherzustellen, dass die Registerkartenleiste im sicheren Bereich über der Startlinie angezeigt wird.

Wenn Sie beispielsweise Ihre TabBar programmgesteuert erstellen, ersetzen Sie sie

self.tabBarController = [[UITabBarController alloc] init];
self.window.rootViewController = self.tabBarController;

Mit diesem:

#define IS_IPHONEX (([[UIScreen mainScreen] bounds].size.height-812)?NO:YES)
self.tabBarController = [[UITabBarController alloc] init];    
self.window.rootViewController = [[UIViewController alloc] init] ;
if(IS_IPHONEX)
    self.window.rootViewController.view.frame = CGRectMake(self.window.rootViewController.view.frame.origin.x, self.window.rootViewController.view.frame.origin.y, self.window.rootViewController.view.frame.size.width, self.window.rootViewController.view.frame.size.height + 32) ;
[self.window.rootViewController.view addSubview:self.tabBarController.view];
self.tabBarController.tabBar.barTintColor = [UIColor colorWithWhite:0.98 alpha:1.0] ;
self.window.rootViewController.view.backgroundColor = [UIColor colorWithWhite:0.98 alpha:1.0] ;

HINWEIS: Dies kann durchaus ein Fehler sein, da die Ansichtsgrößen und das Layout der Registerkartenleiste vom Betriebssystem festgelegt werden. Es sollte wahrscheinlich gemäß dem Screenshot von Apple in den Richtlinien für die Benutzeroberfläche des iPhone X hier angezeigt werden: https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/


1
Ich sehe, ich habe die Tab-Leiste nicht programmgesteuert erstellt, sondern das Storyboard verwendet, um sie mit Einschränkungen zu erstellen, die so festgelegt sind, dass sie am unteren Bildschirmrand angezeigt werden. Es kommt mir seltsam vor, dass wir feststellen müssen, ob es sich um ein iPhone X handelt, und dann das Layout neu ausrichten müssen, während sie die Höhe der TabBar selbst ohne Codeänderungen erhöhen.
Adrian Chen

Das fühlt sich für mich jetzt eher wie ein Fehler an. Ich denke, ich werde einen Fehlerbericht darüber erstellen und sehen, was dabei herauskommt. Danke für Ihre Hilfe!!
Adrian Chen

Es ist wirklich keine gute Idee, die genaue Höhe der Hauptbildschirmgrenzen zu verwenden, um festzustellen, ob die App auf dem iPhone X ausgeführt wird. Was passiert, wenn das Modell des nächsten Jahres dieselbe Punktgröße hat? Oder wenn die App im Querformat läuft?
Roperklacks

Transparenz scheint keinen Einfluss darauf zu haben, dass meine Symbole nicht richtig eingestellt sind. Sie sind durcheinander, ob die UITabBar undurchsichtig oder transparent ist.
Adama

Es scheint, dass Sie tatsächlich 32 Pixel zur Höhe des Rahmens hinzufügen, anstatt davon zu subtrahieren?
Perry

2

Mein Fall war, dass ich in meinem UITabBarController eine benutzerdefinierte UITabBar-Höhe festgelegt hatte:

  override func viewWillLayoutSubviews() {            
        var tabFrame = tabBar.frame
        tabFrame.size.height = 60
        tabFrame.origin.y = self.view.frame.size.height - 60
        tabBar.frame = tabFrame
    }

Das Entfernen dieses Codes war die Lösung für die korrekte Anzeige der TabBar auf dem iPhone X.


2

Die einfachste Lösung, die ich gefunden habe, bestand darin, einfach einen Abstand von 0,2 pt zwischen dem unteren Rand der Registerkartenleiste und dem unteren Rand des safeAreaLayoutGuide.bottomAnchor hinzuzufügen.

tabBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -0.2)

1

Ich hatte das gleiche Problem, als ich versuchte, den Rahmen von UITabBar in meinem benutzerdefinierten TabBarController festzulegen.

self.tabBar.frame = CGRectMake(0, self.view.frame.size.height - kTabBarHeight, self.view.frame.size.width, kTabBarHeight);

Als ich es gerade auf die neue Größe eingestellt habe, ist das Problem behoben

if(IS_IPHONE_X){
    self.tabBar.frame = CGRectMake(0, self.view.frame.size.height - kPhoneXTabBarHeight, self.view.frame.size.width, kPhoneXTabBarHeight);
}
else{
    self.tabBar.frame = CGRectMake(0, self.view.frame.size.height - kTabBarHeight, self.view.frame.size.width, kTabBarHeight);
}

1
Was sind die Werte von kPhoneXTabBarHeight ?
Tiago Veloso

Ich habe gerade 32 Punkte zum vorherigen Wert von kTabBarHeight (der 45 war) hinzugefügt. Sie müssen jedoch nicht genau den gleichen Wert angeben. Für mich funktioniert dies auch ohne Angabe des Rahmens für die Registerkartenleiste. Aber wenn Sie es angeben, müssen Sie für zusätzliche Höhe auf dem iPhone X anpassen.
Evgeny

1
Totaler Hack, aber es war die einzige dieser Lösungen, die es für mich richtig aussehen ließ.
Kenny Wyland

Wenn Sie eine benutzerdefinierte Ansicht als Registerkarte haben, möchten Sie diesen Hack verwenden, um Ihre benutzerdefinierte Ansicht für das iPhone X anzupassen.
Hemang

1
@Hemang nein, es war 45 für dieses Projekt, von dem ich diesen Code ausgeliehen habe.
Evgeny

1

Ich habe dies heute mit einer UITabBar festgestellt, die manuell zum Ansichts-Controller im Storyboard hinzugefügt wurde. Wenn ich mich mit einer Konstante von 0 am unteren Rand des sicheren Bereichs ausrichte, wird das Problem angezeigt, aber wenn ich es auf 1 ändere, wird das Problem behoben. Die UITabBar um 1 Pixel höher als normal zu haben, war für meine Anwendung akzeptabel.


Hat bei mir nicht funktioniert. Ich habe eine UITabBar verwendet, die ebenfalls manuell hinzugefügt wurde.
Kenny Wyland

1

Ich habe mir über dieses Problem den Kopf gekratzt. Es scheint damit verbunden zu sein, wie die tabBar initialisiert und zur Ansichtshierarchie hinzugefügt wird. Ich habe auch die oben genannten Lösungen wie Aufrufen invalidateIntrinsicContentSize, Festlegen des Frames und auch bottomInsetsinnerhalb einer UITabBar-Unterklasse ausprobiert. Sie scheinen jedoch vorübergehend zu funktionieren und brechen ein anderes Szenario ab oder regressieren die Registerkartenleiste, indem sie ein mehrdeutiges Layoutproblem verursachen. Als ich das Problem debuggte, habe ich versucht, die Höhenbeschränkungen der UITabBar und centerYAnchor zuzuweisen, aber beide haben das Problem nicht behoben. Im View-Debugger wurde mir klar, dass die TabBar-Höhe vor und nach der Reproduktion des Problems korrekt war, was mich zu der Annahme veranlasste, dass das Problem in den Unteransichten lag. Ich habe den folgenden Code verwendet, um dieses Problem erfolgreich zu beheben, ohne ein anderes Szenario zu regressieren.

- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    if (DEVICE_IS_IPHONEX())
    {
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            for (UIView *view in self.tabBar.subviews)
            {
                if ([NSStringFromClass(view.class) containsString:@"UITabBarButton"])
                {
                    if (@available (iOS 11, *))
                    {
                        [view.bottomAnchor constraintEqualToAnchor:view.superview.safeAreaLayoutGuide.bottomAnchor].active = YES;
                    }
                }
            }
        } completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            [self.tabBar layoutSubviews];
        }];
    }
}

Annahmen: Ich mache dies nur für das iPhone X, da es derzeit auf keinem anderen Gerät reproduziert zu werden scheint. Basiert auf der Annahme, dass Apple den Namen der UITabBarButton-Klasse in zukünftigen iOS-Versionen nicht ändert. Wir tun dies nur auf UITabBarButton, wenn Apple mehr interne Unteransichten zu UITabBar hinzufügt, müssen wir möglicherweise den Code ändern, um dies anzupassen.

Bitte lassen Sie mich wissen, ob dies funktioniert, offen für Vorschläge und Verbesserungen!

Es sollte einfach sein, dafür ein schnelles Äquivalent zu erstellen.


Ich habe das viewDidAppear(animated:)in mein UITabBarControllerund es hat gut funktioniert. Vielen Dank!
Albert Bori

1
Welcher Parameter hat Größe und Koordinator übergeben? aus der Sicht didAppear
sulabh

1

Aus diesem Tutorial:

https://github.com/eggswift/ESTabBarController

und nach der Initialisierung der Registerkartenleiste wird diese Zeile in die Appdelegate-Klasse geschrieben

(self.tabBarController.tabBar as? ESTabBar)?.itemCustomPositioning = .fillIncludeSeparator

Löst mein Problem mit der Registerkartenleiste.

Hoffe, es löst Ihr Problem

Vielen Dank


1

Wählen Sie die Registerkarte und aktivieren Sie das Kontrollkästchen "Relative Ränder des Bereichs speichern" im Inspektor-Editor wie folgt:

Geben Sie hier die Bildbeschreibung ein


1

Ich hatte das ähnliche Problem, zuerst wurde es korrekt gerendert, aber nach dem Einrichten badgeValueauf einem der tabBarItem wurde das Layout beschädigt. Was für mich ohne Unterklasse funktioniert hat, UITabBarwar dies in meiner bereits erstellten UITabBarControllerUnterklasse.

-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLayoutYAxisAnchor *tabBarBottomAnchor = self.tabBar.bottomAnchor;
    NSLayoutYAxisAnchor *tabBarSuperviewBottomAnchor = self.tabBar.superview.bottomAnchor;
    [tabBarBottomAnchor constraintEqualToAnchor:tabBarSuperviewBottomAnchor].active = YES;
    [self.view layoutIfNeeded];
}

Ich habe die tabBar-Übersicht verwendet, um sicherzustellen, dass sich die Einschränkungen / Anker in derselben Ansichtshierarchie befinden, und um Abstürze zu vermeiden.

Nach meinem Verständnis müssen wir, da dies ein UIKit-Fehler zu sein scheint, nur die Einschränkungen der Registerkartenleiste neu schreiben / neu festlegen, damit die automatische Layout-Engine die Registerkartenleiste wieder korrekt gestalten kann.


0

Wenn Sie Höhenbeschränkungen für die Registerkartenleiste haben, entfernen Sie diese.

Konfrontiert das gleiche Problem und das Entfernen dieses löste das Problem.


0

Ich habe einen neuen UITabBarController in meinem Storyboard erstellt und alle View Controller auf diesen neuen UITabBarConttoller verschoben. Also funktionieren alle gut im iPhone X Simulator.


Dies hat es auch für mich behoben. Die Art und Weise, wie Xcode 9 IB das XML des UITabBarController generiert, das das Problem behoben hat, hat etwas anderes.
Tiago

0

Für das iPhone können Sie dies tun, Unterklasse UITabBarController.

class MyTabBarController: UITabBarController {

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if #available(iOS 11, *) {
        self.tabBar.heightAnchor.constraint(equalToConstant: 40).isActive = true
        self.tabBar.invalidateIntrinsicContentSize()
    }
  }
}

Gehen Sie zum Storyboard und erlauben Sie Use Safe Area Layout Guide und ändern Sie die Klasse von UITabbarController in MyTabBarController

PS Diese Lösung wird nicht für universelle Anwendungen und iPad getestet.


0

Versuchen Sie, den Begrüßungsbildschirm mit der Größe @ 3x (3726 × 6624) zu ändern.


Was ist, wenn wir ein LaunchScreen-Storyboard verwenden?
Avineet Gupta

Es ist in Ordnung, verwenden Sie einfach die neue Größe Splash
Sob7y

0

Entfernen Sie für mich die [self.tabBar setBackgroundImage:]Arbeit, vielleicht ist es ein UIKit-Fehler


0

Für mich hat dies alle Probleme behoben:

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let currentHeight = tabBar.frame.height
        tabBar.frame = CGRect(x: 0, y: view.frame.size.height - currentHeight, width: view.frame.size.width, height: currentHeight)
    }

0

Ich habe ein UITabBarControllerim Storyboard verwendet und es funktionierte zunächst in Ordnung für mich, aber nach dem Upgrade auf eine neuere Xcode-Version gab es Probleme mit der Höhe der Registerkartenleiste.

Für mich bestand die Korrektur darin, das vorhandene UITabBarControlleraus dem Storyboard zu löschen und durch Ziehen aus der Objektbibliothek des Interface Builder neu zu erstellen .


0

Für diejenigen, die ganz UITabBarControllerprogrammgesteuert schreiben , können Sie die Titelposition UITabBarItem.appearance().titlePositionAdjustmentanpassen

Wenn Sie also in diesem Fall eine Lücke zwischen Symbol und Titel hinzufügen möchten, verwenden Sie diese in viewDidLoad:

    override func viewDidLoad() {
        super.viewDidLoad()

        // Specify amount to offset a position, positive for right or down, negative for left or up
        let verticalUIOffset = UIOffset(horizontal: 0, vertical: hasTopNotch() ? 5 : 0)

        UITabBarItem.appearance().titlePositionAdjustment = verticalUIOffset
    }

Erkennen, ob das Gerät einen Notch-Bildschirm hat:

  func hasTopNotch() -> Bool {
      if #available(iOS 11.0, tvOS 11.0, *) {
        return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 20
      }
      return false
  }

-1

Ich hatte das gleiche Problem, das durch Festlegen der Elemente der Registerkartenleiste nach dem Anlegen der Registerkartenleiste behoben wurde.

In meinem Fall trat das Problem auf, wenn:

  1. Es gibt einen benutzerdefinierten Ansichtscontroller
  2. Eine UITabBar wird im Initialisierer des View Controllers erstellt
  3. Die Elemente der Registerkartenleiste werden festgelegt, bevor die Ansicht geladen wurde
  4. In der Ansicht wurde die Registerkartenleiste zur Hauptansicht des Ansichtscontrollers hinzugefügt
  5. Anschließend werden die Elemente wie erwähnt gerendert.

-1

Ich denke, das ist ein Fehler UIKit von iPhoneX. weil es funktioniert:

if (@available(iOS 11.0, *)) {
    if ([UIApplication sharedApplication].keyWindow.safeAreaInsets.top > 0.0) {
       self.tabBarBottomLayoutConstraint.constant = 1.0;
    }
} 

Können Sie weitere Informationen zu tabBarBottomLayoutConstraint geben?
user3099837

-1

Ich glaube, Sie legen möglicherweise die Registerkartenleiste gegen die untere sichere Layoutanleitung. Dies ist wahrscheinlich nicht das, was Sie möchten, da die Registerkartenleiste anscheinend ihre eigenen Berechnungen durchführt, um die Elemente der Registerkartenleiste sicher über der Startzeile im iPhone X zu positionieren . Richten Sie Ihre untere Einschränkung gegen die untere Ansicht ein . Sie sollten sehen, dass es sowohl auf dem iPhone X als auch auf anderen iPhones korrekt dargestellt wird .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.