Темная тень на панели навигации при переходе на переход после обновления до Xcode 5.1 и iOS 7.1


92

Когда я перемещаюсь между родительским и дочерним контроллерами в главном контроллере навигации, я вижу темную тень с правой стороны панели навигации вверху. Это началось после того, как я обновился до Xcode 5.1. Это грубо и отвлекает. Как мне от этого избавиться?

Ответы:


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

Я решил эту проблему, установив цвет фона представления контроллера навигации.


На самом деле это очень хороший ответ. По какой-то причине Interface Builder не позволяет вам получить доступ к представлению вашего контроллера навигации, но похоже, что darkColorпредставление все еще существует, и вызывает эту проблему.
superarts.org

1
Это отличный ответ, потому что он также позволяет полосе оставаться полупрозрачной, не показывая уродливых черных участков, которые просачиваются из контроллера навигации. Просто хотелось бы, чтобы был способ настроить его в раскадровке.
димигуэль

В яблочко. Время от времени я думаю об этом и немного разочаровываюсь в других ответах, которые предлагают отключить прозрачность панели навигации, поскольку в основном они решают эту проблему, отключив функцию, которая в этом ответе указывает на фактическое исправление. Жаль, что это поведение остается неизменным в Xcode 7 / iOS 9.
superarts.org

1
Извините, я отклонил этот ответ, потому что фон окна не является основной причиной этой проблемы. Пожалуйста, посмотрите мой прикрепленный скриншот: imgur.com/a/SH5Dp. Вы обнаружите, что проблема все еще существует, темный оттенок только что заменен на белый, я полагаю, что контроллер деталей «обрезан» или как-то так, он ничего не рисует под NavBar .
mariotaku

1
tabBarController? .view.backgroundColor = UIColor.white в случае, если корневым контроллером является UITabBarController.
Вишал Сингх

55
self.navigationController.navigationBar.translucent = NO; 

Для новых версий Swift:

navigationController?.navigationBar.isTranslucent = false

Где ты это разместил?
Зорайр 07

В методе ViewDidLoad главного контроллера представления
Нихат


я думаю, что это действительно правильный ответ. navigationController.view.backgroundColor = .whiteбольше не работает на прошивке 11.
AnBisw

1
@Annjawn, navigationController.view.backgroundColor = .whiteработает на iOS 12. Удаление полупрозрачного с панели навигации не может использоваться в ситуации, когда это необходимо, а черная тень - нет.
Alex Motor

38

ответ nonamelive идеален. Чтобы добиться того же в Интерфейсном Разработчике И ЕЩЕ СОХРАНИТЬ ПРОЗРАЧНОСТЬ , выберите контроллер навигации и установите определяемый пользователем атрибут времени выполнения, view.backgroundColorкак показано на снимке экрана (в Инспекторе идентичности). Повторите эти действия для всех контроллеров навигации, которые обнаруживают эту проблему.

Похоже, что вся эта проблема возникает из-за того, что черный цвет (или на самом деле без цвета) UINavigationController просачивается в то время, когда CoreGraphics делает снимки в начале анимации. Таким образом, установка белого цвета предотвратит это.

Инспектор идентичности -> Пользовательские атрибуты времени выполнения


1
Я предпочитаю этот подход, позволяя Interface Builder UI загружать как можно больше.
DazChong

iOS 8.4 не помогла
Максим Князев

3
Отлично работает с Xcode 8.3.3. Просто чтобы еще раз подчеркнуть, он должен быть UINavigationControllerвключен, а не на viewController.
jungledev 06

У меня был navcon в tabcon, и я видел тени на обеих полосах (верхней и нижней) при использовании «Скрывает нижнюю панель при нажатии» на одном из VC navcon. Установка белого фона на navcon исправила обе тени. Благодарность!
nh32rg,

6

Похоже, это ошибка, появившаяся в iOS 7.1. В моем случае это вызвано расположением UIToolbar непосредственно под панелью навигации. Темная тень также появляется на полупрозрачной панели вкладок.

Тень, похоже, вызвана фоновым изображением UIToolbar. Теперь я использую этот обходной путь в контроллере представления с панелью инструментов, которая скрывает фоновое представление панели инструментов во время перехода:

- (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;
    }
}

Это код для [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

Я подал этот радар: http://openradar.appspot.com/16418845


2
Ваше решение подойдет, если вам не нужна полупрозрачная панель навигации.
Tom

Есть более простой способ получить backgroundView. [self.toolbar valueForKey:@"_backgroundView"]. Обратите внимание, что это частный API, но я думаю, что Apple вас не поймает, потому что _backgroundViewэто просто общее имя.
nonamelive

Этот ответ подсказал мне, что мне нужно было сделать. В моем случае это было так же просто, как снятие флажка с опции полупрозрачности на UIToolbar в построителе интерфейса.
Greg W

4

Кажется, это происходит с любой полупрозрачной панелью (TabBar или ToolBar).
Итак, один из способов исправить это - установить _tabBar.translucent = NO;(в моем случае). Это предотвращает нежелательную тень под верхней панелью навигации, оставляя панель навигации полупрозрачной. К сожалению, нижняя полоса больше не полупрозрачна.

Его можно снова сделать полупрозрачным, но все это должно произойти после завершения всей анимации нажатия, поэтому переключение этого свойства хорошо заметно.

Однако в случае, если нижняя панель также должна быть полупрозрачной, и я не хочу, чтобы пользователь видел изменение, я решил это следующим образом:

/*  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];
                 }];

Затем viewDidAppear:я просто возвращаю это обратно:

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

Во внешнем виде есть небольшое изменение, но оно едва заметно, и это лучше, чем тень под панелью навигации.

Надеюсь, что это поможет другим сохранить полупрозрачность полос, пока Apple не исправит это поведение, поскольку в некоторых случаях полосы ПРЕДНАЗНАЧЕНЫ для скрытия, в отличие от того, что предлагалось в других сообщениях, особенно для UITabBar


Мне удалось решить эту проблему, приняв решение @manmal - определив атрибут времени выполнения view.backgroundColorдля вашего UITabBarController в раскадровке и установив для него белый цвет.
jamesk

4

Это работает для меня в Swift

В AppDelegateна didFinishLaunchingWithOptionsметоде, я установил следующее:

UIApplication.shared.windows.first?.backgroundColor = .white

4

У меня это работает на iOS 13 как со светлой, так и с темной темами, а также со старыми версиями iOS.

Добавьте в application(didFinishLaunchingWithOptions)метод AppDelegate следующий код :

if #available(iOS 13.0, *) {
    window?.backgroundColor = UIColor.systemBackground
} else {
    window?.backgroundColor = UIColor.white
}

Я тоже пробовал этот метод, но столкнулся с проблемой при представлении контроллера представления в режиме по умолчанию. Тогда вы увидите белый фон окна вместо черного. Это выглядит странно. не могли бы вы предложить какую-либо идею, как преодолеть эту ситуацию
Варун в наир

3

Вот мой вариант ... он требует гораздо меньше кода, чем ответ Тома, и более эффективен. Это ЕСЛИ вам нужна полупрозрачная панель навигации, а также вы хотите исправить эту проблему с тенями.

В исходном ViewController (который встроен в контроллер навигации) ...

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

а также

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

Результат такой же, как у Тома (визуально для конечного пользователя), и его проще реализовать. Надеюсь это поможет...


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

Это работает для меня, поместите его внутри функции, в которой вы нажимаете новый ViewController


Безумно, но среди всех ответов идея поместить его в функцию, перемещающую следующий VC, была единственной!
Coltuxumab

3

Следующее также работает и оставляет панель навигации прозрачной:

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


1

Хотя это не то же самое, что стандартная реализация iOS, это хороший способ решить проблему:

- (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;
    }];
}

Вы получите красивую анимацию нарастания / исчезновения панели вкладок. Добавьте код в корень UIViewController.


-1

Или, если вы используете конструктор интерфейса, вы можете просто выбрать панель навигации на своем контроллере навигации и снять флажок полупрозрачный между стилем и оттенком полосы в инспекторе атрибутов, чтобы избавиться от этого странного эффекта -

Инспектор

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.