Dunkler Schatten auf der Navigationsleiste während des Übergangs nach dem Upgrade auf Xcode 5.1 und iOS 7.1

91

Wenn ich in einem Master-Detail-Navigationscontroller zwischen übergeordneten und untergeordneten Controllern hin und her navigiere, sehe ich oben rechts in der Navigationsleiste einen dunklen Schatten. Es begann, nachdem ich auf Xcode 5.1 aktualisiert hatte. Es fühlt sich rau und ablenkend an. Wie kann ich es loswerden?

Nihat
quelle

Antworten:

143
self.navigationController.view.backgroundColor = [UIColor whiteColor];

Ich habe dieses Problem gelöst, indem ich die Hintergrundfarbe der Ansicht des Navigationscontrollers festgelegt habe.

nichtschmelzend
quelle
Diese Antwort ist eigentlich sehr gut. Aus irgendeinem Grund können Sie mit Interface Builder nicht auf die Ansicht Ihres Navigationscontrollers zugreifen, aber es sieht so aus, als ob eine darkColorAnsicht noch vorhanden ist, und verursacht dieses Problem.
Superarts.org
1
Dies ist eine großartige Antwort, da die Leiste dadurch auch durchscheinend bleibt, ohne den hässlichen schwarzen Bereich anzuzeigen, der vom Navigationscontroller durchblutet. Ich wünschte nur, es gäbe eine Möglichkeit, es im Storyboard einzurichten.
Dimiguel
Genau. Von Zeit zu Zeit denke ich darüber nach und bin etwas enttäuscht über die anderen Antworten, die darauf hindeuten, die Transparenz der Navigationsleiste zu deaktivieren, da sie dieses Problem im Grunde durch Deaktivieren einer Funktion lösen, die in dieser Antwort auf die eigentliche Lösung hinweist. Schade, dass dieses Verhalten in Xcode 7 / iOS 9 gleich bleibt.
superarts.org
1
Entschuldigung, ich habe diese Antwort abgelehnt, da der Fensterhintergrund nicht die Hauptursache für dieses Problem ist. Bitte sehen Sie meinen Screenshot im Anhang: imgur.com/a/SH5Dp Sie werden feststellen, dass das Problem immer noch besteht, der dunkle Farbton wurde gerade durch einen weißen ersetzt. Ich denke, der Detail-Controller wurde "abgeschnitten" oder irgendwie, er zeichnet nichts unter NavBar .
Mariotaku
1
tabBarController? .view.backgroundColor = UIColor.white, falls der Root-Controller UITabBarController ist.
Vishal Singh
53
self.navigationController.navigationBar.translucent = NO; 

behoben

Nihat
quelle
Wo hast du das platziert?
Zorayr
In der ViewDidLoad-Methode des Master View Controllers
Nihat
in viewDidAppear hinzufügen
Abdul Waheed
Ich denke, das ist eigentlich die richtige Antwort. das navigationController.view.backgroundColor = .whitefunktioniert nicht mehr unter iOS 11.
AnBisw
1
@Annjawn, navigationController.view.backgroundColor = .whitefunktioniert unter iOS 12. Das Entfernen von durchscheinend aus der Navigationsleiste kann nicht in Situationen verwendet werden, in denen dies erforderlich ist, schwarzer Schatten jedoch nicht.
Alex Motor
38

Die Antwort von nonamelive ist perfekt. Um dasselbe in Interface Builder zu erreichen UND DIE ÜBERTRAGUNG NOCH ZU BEHALTEN , wählen Sie den Navigationscontroller aus und legen Sie ein benutzerdefiniertes Laufzeitattribut fest, view.backgroundColorwie im Screenshot (im Identitätsinspektor) gezeigt. Wiederholen Sie diesen Vorgang für alle Navigationscontroller, bei denen dieses Problem auftritt.

Es scheint, dass dieses ganze Problem auftritt, weil die schwarze Farbe (oder eigentlich keine Farbe) von UINavigationController zu dem Zeitpunkt durchläuft, zu dem CoreGraphics-Snapshots zu Beginn der Animation erstellt werden. Wenn Sie es also auf Weiß setzen, wird dies verhindert.

Identity Inspector -> Benutzerdefinierte Laufzeitattribute

manmal
quelle
1
Ich bevorzuge diesen Ansatz, lasse Interface Builder UI so viel wie möglich.
DazChong
iOS 8.4 hat nicht geholfen
Maksim Kniazev
3
Funktioniert perfekt mit Xcode 8.3.3. Nur um noch einmal zu betonen, muss UINavigationControlleraktiviert werden, nicht auf dem viewController.
Jungledev
Ich hatte ein Navcon in einem Tabcon und sah Schatten auf beiden Balken (oben und unten), als ich "Versteckte untere Leiste beim Drücken" auf einem der VCs des Navcons verwendete. Durch Einstellen des weißen Hintergrunds auf dem Navcon wurden beide Schatten korrigiert. Vielen Dank!
nh32rg
6

Dies scheint ein Fehler zu sein, der in iOS 7.1 eingeführt wurde. In meinem Fall wird dies durch eine UIToolbar verursacht, die direkt unter der Navigationsleiste platziert ist. Der dunkle Schatten wird auch in der durchscheinenden Registerkartenleiste angezeigt.

Der Schatten scheint durch die Hintergrundansicht der UIToolbar verursacht zu werden. Ich verwende diese Problemumgehung jetzt im Ansichts-Controller mit der Symbolleiste, die die Hintergrundansicht der Symbolleiste während des Übergangs verbirgt:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    UIView *toolbarBackgroundView = [self.toolbar findViewRecursively:^BOOL(UIView *subview, BOOL *stop) {
        BOOL isToolbarBackgroundView = ([subview isKindOfClass:[UIImageView class]]
                                        && [NSStringFromClass(subview.class) isEqualToString:@"_UIToolbarBackground"]);
        if (isToolbarBackgroundView) {
            *stop = YES;
        }
        return (! isToolbarBackgroundView);
    }];
    if (toolbarBackgroundView) {
        // fade toolbar background view back in
        [UIView animateWithDuration:0.1f animations:^{
            toolbarBackgroundView.alpha = 1.0f;
        }];
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    UIView *toolbarBackgroundView = [self.toolbar findViewRecursively:^BOOL(UIView *subview, BOOL *stop) {
        BOOL isToolbarBackgroundView = ([subview isKindOfClass:[UIImageView class]]
                                        && [NSStringFromClass(subview.class) isEqualToString:@"_UIToolbarBackground"]);
        if (isToolbarBackgroundView) {
            *stop = YES;
        }
        return (! isToolbarBackgroundView);
    }];
    if (toolbarBackgroundView) {
        // hide toolbar background view
        toolbarBackgroundView.alpha = 0.0f;
    }
}

Dies ist der Code für [UIView findViewRecursively:]

@interface UIView (FindSubview)

- (UIView*)findViewRecursively:(BOOL(^)(UIView* subview, BOOL* stop))recurse;

@end

@implementation UIView (FindSubview)

- (UIView*)findViewRecursively:(BOOL(^)(UIView* subview, BOOL* stop))recurse {
    for (UIView* subview in self.subviews) {
        BOOL stop = NO;
        if (recurse(subview, &stop)) {
            UIView* view = [subview findViewRecursively:recurse];
            if (view) return view;
        } else if (stop) {
            return subview;
        }
    }
    return nil;
}

@end

Ich habe dieses Radar abgelegt: http://openradar.appspot.com/16418845

Tom
quelle
2
Ihre Lösung ist in Ordnung, wenn Sie keine durchscheinende Navigationsleiste wünschen.
Tom
Es gibt einen einfacheren Weg, um das zu bekommen backgroundView. [self.toolbar valueForKey:@"_backgroundView"]. Bitte beachten Sie, dass dies eine private API ist, aber ich denke, Sie werden nicht von Apple erwischt, da _backgroundViewes sich nur um einen generischen Namen handelt.
Nonamelive
Diese Antwort gab mir einen Hinweis darauf, was ich tun musste. In meinem Fall war es so einfach wie das Deaktivieren der durchscheinenden Option in der UIToolbar im Interface Builder.
Greg W
4

Es scheint mit jeder Leiste (TabBar oder ToolBar) zu passieren, die durchscheinend ist.
Eine Möglichkeit, dies zu beheben, besteht darin, die _tabBar.translucent = NO;(in meinem Fall) festzulegen. Dies verhindert den unerwünschten Schatten unter der oberen Navigationsleiste, während die Navigationsleiste durchscheinend bleibt. Leider ist die untere Leiste nicht mehr durchscheinend.

Es kann wieder auf durchscheinend gesetzt werden, aber all dies muss geschehen, nachdem die gesamte Push-Animation beendet ist, sodass das Umschalten dieser Eigenschaft gut erkennbar ist.

Für den Fall, dass die untere Leiste jedoch auch durchscheinend sein muss und ich nicht möchte, dass der Benutzer die Änderung sieht, habe ich sie wie folgt gelöst:

/*  create a simple quick animation of the bottom bar
    just before pushing the new controller */
[UIView animateWithDuration:0.1
                 animations:^{
                     _tabBar.barTintColor = [UIColor colorWithWhite:0.97254901960784 alpha:1.0]; // this is the closest color for my case
                     _tabBar.translucent = NO;
                 } completion:^(BOOL finished) {
                     /* now when the animation that makes the bar not translucent
                        is finished we can push the new controller
                        the controller is instantiated before the animation code */
                     [self.navigationController pushViewController:controller animated:YES];
                 }];

Dann viewDidAppear:kehrt ich das einfach zurück:

[UIView animateWithDuration:0.1
             animations:^{
                     _tabBar.barTintColor = nil;
                     _tabBar.translucent = YES;
                 }];

Es gibt nur eine kleine Änderung im Erscheinungsbild, aber es ist kaum wahrnehmbar und viel besser als der Schatten unter der Navigationsleiste.

Hoffe, es wird anderen helfen, Balken durchscheinend zu halten, bis Apple dieses Verhalten behebt, da Balken in einigen Fällen ausgeblendet werden sollen, anders als es in anderen Posts speziell für die vorgeschlagen wurde UITabBar

Kacho
quelle
Ich konnte dieses Problem beheben, indem ich die Lösung von @ manmal übernahm: Definieren Sie das Laufzeitattribut view.backgroundColorfür Ihren UITabBarController im Storyboard und setzen Sie es auf eine weiße Farbe.
Jamesk
4

Das funktioniert bei mir in Swift

In der AppDelegateon- didFinishLaunchingWithOptionsMethode setze ich Folgendes:

UIApplication.shared.windows.first?.backgroundColor = .white
Pableiros
quelle
4

Dies funktioniert bei iOS 13 mit hellen und dunklen Themen sowie bei älteren iOS-Versionen.

Fügen Sie dem AppDelegate den folgenden Code zur application(didFinishLaunchingWithOptions)Methode hinzu:

if #available(iOS 13.0, *) {
    window?.backgroundColor = UIColor.systemBackground
} else {
    window?.backgroundColor = UIColor.white
}
petrsyn
quelle
Ich habe diese Methode ebenfalls ausprobiert, aber es tritt ein Problem auf, wenn ein Ansichts-Controller im Standardmodus angezeigt wird. Dann sehen Sie den weißen Hintergrund des Fensters anstelle des schwarzen. Das sieht komisch aus. können Sie bitte eine Idee vorschlagen, um diese Situation zu überwinden
varun v nair
3

Hier ist meine Variante ... sie erfordert viel weniger Code als Toms Antwort und ist effizienter. Dies ist WENN Sie eine durchscheinende Navigationsleiste wünschen und auch dieses Schattenproblem beheben möchten.

Im Quell-ViewController (der in den Navigations-Controller eingebettet ist) ...

- (void)viewDidAppear:(BOOL)animated
{
     self.navigationController.navigationBar.translucent = YES;
}

und

 - (void)viewWillDisappear:(BOOL)animated
 {
     self.navigationController.navigationBar.translucent = NO;
 }

Das Ergebnis entspricht dem von Tom (visuell für den Endbenutzer) und ist einfacher zu implementieren. Hoffe das hilft...

user2734823
quelle
3
self.navigationController!.navigationBar.translucent = false;

Dies funktioniert bei mir. Platzieren Sie es in der Funktion, in der Sie den neuen ViewController drücken

Shyam Raju
quelle
Verrückt, aber unter allen Antworten war die Idee, es in die Funktion zu setzen, die zum nächsten VC pusht, diejenige!
Coltuxumab
3

Folgendes funktioniert ebenfalls und lässt die Navigationsleiste transparent:

[UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor whiteColor];

seb
quelle
1

Es ist zwar nicht dasselbe wie die Standard-iOS-Implementierung, aber dies ist eine gute Möglichkeit, das Problem zu beheben:

- (void)viewWillAppear:(BOOL)animated {
    [UIView animateWithDuration:0.35f animations:^{
        self.tabBarController.tabBar.alpha = 1.0f;
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
    [UIView animateWithDuration:0.35f animations:^{
        self.tabBarController.tabBar.alpha = 0.0f;
    }];
}

Sie erhalten eine schöne Ein- / Ausblendanimation der Registerkartenleiste. Fügen Sie den Code im Stammverzeichnis hinzu UIViewController.

nikolovski
quelle
-1

Wenn Sie den Interface Builder verwenden, können Sie einfach die Navigationsleiste in Ihrem Navigationscontroller auswählen und das Kontrollkästchen Durchscheinend zwischen Stil und Balkentönung im Attributinspektor deaktivieren, um diesen seltsamen Effekt zu beseitigen.

Inspektor

Anfänger
quelle