Kiedy nawiguję tam i z powrotem między kontrolerami nadrzędnymi i podrzędnymi w kontrolerze nawigacyjnym nadrzędnym - szczegóły, widzę ciemny cień po prawej stronie paska nawigacyjnego u góry. Zaczęło się po uaktualnieniu do Xcode 5.1. Jest szorstki i rozpraszający. Jak mogę się go pozbyć?
91
darkColor
widok wciąż tam jest i powoduje ten problem.self.navigationController.navigationBar.translucent = NO;
Nowsze wersje Swift:
navigationController?.navigationBar.isTranslucent = false
źródło
navigationController.view.backgroundColor = .white
już nie działa na iOS 11.navigationController.view.backgroundColor = .white
działa na iOS 12. Usunięcie półprzezroczystego z paska nawigacji nie może być używane w sytuacji, gdy jest to potrzebne, ale czarny cień nie.odpowiedź nonamelive jest doskonała. Aby osiągnąć to samo w programie Interface Builder I WCIĄŻ ZACHOWAĆ TRANSLUCENCY , wybierz kontroler nawigacji i ustaw zdefiniowany przez użytkownika atrybut środowiska wykonawczego,
view.backgroundColor
jak pokazano na zrzucie ekranu (w Inspektorze tożsamości). Powtórz te czynności dla wszystkich kontrolerów nawigacji, które mają ten problem.Wygląda na to, że cały ten problem występuje, ponieważ czarny kolor (a właściwie brak koloru) UINavigationController przecieka w momencie, gdy CoreGraphics wykonuje migawkę na początku animacji. Więc ustawienie go na biały zapobiegnie temu.
źródło
UINavigationController
, a nie na kontrolerze viewController.Wygląda na to, że jest to błąd wprowadzony w iOS 7.1. W moim przypadku jest to spowodowane przez pasek narzędzi UIT umieszczony bezpośrednio pod paskiem nawigacji. Ciemny cień pojawia się również na półprzezroczystym pasku kart.
Cień wydaje się być spowodowany widokiem tła paska narzędzi UIToolbar. Teraz używam tego obejścia w kontrolerze widoku z paskiem narzędzi, który ukrywa widok tła paska narzędzi podczas przejścia:
- (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; } }
To jest kod dla
[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
Złożyłem ten Radar: http://openradar.appspot.com/16418845
źródło
backgroundView
.[self.toolbar valueForKey:@"_backgroundView"]
. Pamiętaj, że jest to prywatny interfejs API, ale myślę, że Apple nie złapie Cię, ponieważ_backgroundView
jest to tylko nazwa ogólna.Wydaje się, że dzieje się tak z każdym paskiem (TabBar lub ToolBar), który jest półprzezroczysty.
Tak więc jednym ze sposobów rozwiązania tego problemu jest ustawienie
_tabBar.translucent = NO;
(w moim przypadku). Zapobiega to niepożądanemu cieniu pod górnym paskiem nawigacji, pozostawiając półprzezroczysty pasek nawigacji. Niestety dolny pasek nie jest już przezroczysty.Można ją ustawić z powrotem na półprzezroczystą, ale wszystko to musi nastąpić po zakończeniu całej animacji wypychania, więc przełączanie tej właściwości jest dobrze zauważalne.
W przypadku jednak, gdy dolny pasek również musi być półprzezroczysty i nie chcę, aby użytkownik widział zmianę, rozwiązałem to w następujący sposób:
/* 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]; }];
Następnie w
viewDidAppear:
I po prostu cofam to z powrotem:[UIView animateWithDuration:0.1 animations:^{ _tabBar.barTintColor = nil; _tabBar.translucent = YES; }];
Występuje tylko niewielka zmiana w wyglądzie, ale jest ledwo zauważalna i jest o wiele lepsza niż posiadanie cienia pod paskiem nawigacji.
Mam nadzieję, że pomoże to innym zachować półprzezroczyste paski, dopóki Apple nie naprawi tego zachowania, ponieważ paski SĄ przeznaczone do ukrywania w niektórych przypadkach, w przeciwieństwie do sugerowanych w innych postach, szczególnie dla
UITabBar
źródło
view.backgroundColor
dla swojego UITabBarController w scenorysie i ustaw go na biały kolor.To działa dla mnie w Swift
W
AppDelegate
sprawiedidFinishLaunchingWithOptions
sposobu, ustawić w ten sposób:UIApplication.shared.windows.first?.backgroundColor = .white
źródło
Działa to dla mnie na iOS 13 z jasnymi i ciemnymi motywami, a także na starszych wersjach iOS.
Dodaj następujący kod do AppDelegate do
application(didFinishLaunchingWithOptions)
metody:if #available(iOS 13.0, *) { window?.backgroundColor = UIColor.systemBackground } else { window?.backgroundColor = UIColor.white }
źródło
Oto moja odmiana ... wymaga znacznie mniej kodu niż odpowiedź Toma i jest bardziej wydajna. To jest JEŚLI chcesz mieć przezroczysty pasek nawigacyjny, a także chcesz rozwiązać ten problem z cieniem.
W źródle ViewController (osadzonym w kontrolerze nawigacji) ...
- (void)viewDidAppear:(BOOL)animated { self.navigationController.navigationBar.translucent = YES; }
i
- (void)viewWillDisappear:(BOOL)animated { self.navigationController.navigationBar.translucent = NO; }
Rezultat jest taki sam, jak to, co robi Tom (wizualnie, dla użytkownika końcowego) i jest łatwiejszy do wdrożenia. Mam nadzieję że to pomoże...
źródło
self.navigationController!.navigationBar.translucent = false;
To działa dla mnie, umieść go w funkcji, w której naciskasz nowy ViewController
źródło
Poniższe również działa i pozostawia pasek nawigacji przezroczysty:
[UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor whiteColor];
źródło
Chociaż nie jest to to samo, co standardowa implementacja systemu iOS, jest to dobry sposób na rozwiązanie problemu:
- (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; }]; }
Otrzymasz ładną animację pojawiania się / zanikania paska kart. Dodaj kod w katalogu głównym
UIViewController
.źródło
Lub jeśli korzystasz z narzędzia do tworzenia interfejsu, możesz po prostu wybrać pasek nawigacji z kontrolera nawigacyjnego i odznaczyć pole wyboru Półprzezroczysty między stylem a odcieniem paska w inspektorze atrybutów, aby pozbyć się tego dziwnego efektu -
źródło