Получите нужный цвет на полупрозрачной панели навигации iOS7

Как добиться правильной окраски полупрозрачных панелей навигации в iOS 7? Панель навигации просто изменяет заданный цвет на более яркий. Изменение яркости или насыщенности цвета также не дает нужного результата.

У кого-нибудь такая же проблема? Глядя на Facebook, это как-то работает: у них свои цвета и полупрозрачные панели навигации.

Изменить: просто чтобы прояснить: мне нужно, чтобы панель была полупрозрачной, а не прозрачной (с некоторой альфой), а не сплошной! http://en.wikipedia.org/wiki/Transparency_and_translucency

Изменить: теперь опубликовано в Apple BugReporter


person stk    schedule 19.09.2013    source источник
comment
Я думаю, что с iOS 7.0.3 это больше не нужно, так как теперь устанавливается правильный цвет. Однако вы можете играть с альфа-версией, и размещенные здесь калькуляторы могут вам в этом помочь.   -  person Fábio Oliveira    schedule 25.10.2013


Ответы (20)


Полоса настроит ваши цветовые значения.

Предпочтительный метод, только для RGB> = 40, даст наибольшее размытие

Вы можете использовать этот калькулятор и указать желаемый цвет при отображении на экране, он скажет вам, какой цвет должен быть установлен для barTintColor, поэтому, когда Apple его настроит, он будет отображаться так, как задумано.

https://www.transpire.com/insights/blog/bar-color-calculator/

Изменить: обратите внимание, что эти вычисления предназначены для белого фона и для более светлых цветов (rgb более 40, если вам нужно более темное, вам нужно будет добавить фоновый слой, как упоминалось другими, хотя это уменьшит размытие полосы)

Подробное руководство: https://www.transpire.com/insights/blog/custom-ui-navigationbar-colors-ios7/

Фрагмент:

@interface UnderlayNavigationBar : UINavigationBar

@end

.

@interface UnderlayNavigationBar ()
{
    UIView* _underlayView;
}

- (UIView*) underlayView;

@end

@implementation UnderlayNavigationBar

- (void) didAddSubview:(UIView *)subview
{
    [super didAddSubview:subview];

    if(subview != _underlayView)
    {
        UIView* underlayView = self.underlayView;
        [underlayView removeFromSuperview];
        [self insertSubview:underlayView atIndex:1];
    }
}

- (UIView*) underlayView
{
    if(_underlayView == nil)
    {
        const CGFloat statusBarHeight = 20;    //  Make this dynamic in your own code...
        const CGSize selfSize = self.frame.size;

        _underlayView = [[UIView alloc] initWithFrame:CGRectMake(0, -statusBarHeight, selfSize.width, selfSize.height + statusBarHeight)];
        [_underlayView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
        [_underlayView setBackgroundColor:[UIColor colorWithRed:0.0f green:0.34f blue:0.62f alpha:1.0f]];
        [_underlayView setAlpha:0.36f];
        [_underlayView setUserInteractionEnabled:NO];
    }

    return _underlayView;
}

@end

.

UIViewController* rootViewController = ...;
UINavigationController* navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[UnderlayNavigationBar class] toolbarClass:nil];
[navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:0.0f green:0.0f blue:90.0f/255.0f alpha:1]];
[navigationController setViewControllers:@[rootViewController]];
person SomeGuy    schedule 27.09.2013
comment
Спасибо и +1 за калькулятор! В основном это говорит о том, что вы не можете иметь цвета «темнее», чем 102, при любом значении RGB. Это плохо, потому что мое руководство не позволит мне выбрать любой другой цвет, кроме цветов компании (это RGB 181,27,32), только потому, что так диктует Apple. Должен быть другой способ, потому что Facebook также намного темнее: в текущей версии приложения у него RGB 65,95,156. - person stk; 30.09.2013
comment
Вы все еще можете делать более темные цвета, недостатком является то, что вам нужно добавить вид подложки, чтобы затемнить вещи, а это означает, что чем темнее вы становитесь, тем слабее будет размытие. Мне удалось воссоздать размытие 65,96,156 в Facebook с помощью следующего кода. Я сделал это методом проб и ошибок, цель - сделать альфа-версию colourView как можно более низкой. img707.imageshack.us/img707/3151/482w.png - person SomeGuy; 01.10.2013
comment
У меня все еще было более темное пятно в заголовке, поэтому, чтобы исправить это, я добавил `[navigationBar setBackgroundColor: [[UIColor alloc] initWithWhite: 0.0f alpha: 0.0f]];`. Казалось, работает. - person dclowd9901; 06.10.2013
comment
Вы можете добавить автоматическое изменение размера для поддержки изменения ориентации: colourView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; - person Maciej Swic; 09.10.2013
comment
Хотя на самом деле это не было руководством по простой настройке, я добавил несколько масок с автоизменением размеров и сделал его более динамичным для людей, которые копируют и вставляют, не читая его. - person SomeGuy; 10.10.2013
comment
@SomeGuy Кроме того, я испытываю некоторые странные результаты в iOS 7. Если colorView вставлен в индекс 1, похоже, что он появляется поверх заголовка и текста кнопки «Назад», если вы помещаете другое представление в стек навигации. Если вы поместите его в индекс 0, все будет работать так, как ожидалось. Мысли? - person Maciej Swic; 10.10.2013
comment
@Maciej Swic Я только что добавил несколько исправлений для позиционирования индекса, а также ссылку на мое более подробное сообщение в блоге об использовании более темных цветов в сочетании с размытием на панели навигации в iOS7 - person SomeGuy; 10.10.2013
comment
Существует документ от Apple, в котором описывается, как подобрать оттенок полосы к вашему корпоративному или фирменному цвету developer.apple.com/library/ios/qa/qa1808/_index.html - person Amio; 23.09.2015

Вам просто нужно изменить свойство translucent

navigationBar.translucent = NO;

По сути, это то же самое, что и удаление / создание прозрачных подвидов / подслоев панели навигации.

person malex    schedule 19.09.2014

Я улучшил код из Яркие, яркие цвета для полупрозрачной панели UINavigationBar iOS 7 в моей вилке: https://github.com/allenhsu/CRNavigationController

С моей модификацией цвет результата на экране (выбранный на белом фоне) будет точно таким же, как и значение, переданное в setBarTintColor. Думаю, это отличное решение.

person Allen Hsu    schedule 23.10.2013
comment
@MatthewCrenshaw: Я все еще считаю, что с iOS 7.0.3 @AllenHsu CRNavigationController работает лучше всего, даже если ваш цвет исключительно яркий. - person SwiftArchitect; 27.01.2014
comment
Лучше всего это работает с моими панелями навигации цвета Tungsten на iOS 8. - person lifjoy; 07.09.2015

Я знаю, что этот ответ немного запоздал, но если вы используете Interface Builder, вы можете получить неправильный цвет при использовании шестнадцатеричного значения, потому что Interface Builder настроен на использование неправильного цветового пространства. В Xcode 6.4 вы можете нажать маленькую шестеренку в правом верхнем углу диалогового окна выбора цвета, чтобы выбрать, какое цветовое пространство вы используете:

введите здесь описание изображения

Мой был установлен на sRGB IEC6196-2.1, тогда как мне действительно следовало использовать Generic RGB.

person Elethier    schedule 17.08.2015
comment
Вау, чувак, ты сделал мой день! Это решило мою проблему. Большое спасибо! - person Perjan Duro; 29.08.2015

Если ваш цвет не слишком яркий, вы можете рассчитать эквивалентный цвет с альфа-каналом. Это хорошо работает в iOS 7.0.3+; до 7.0.3 он автоматически применял альфа 0,5.

В этом коде предполагается, что ваш входной цвет - RGB и непрозрачен, а цвет фона - белый:

- (UIColor *) colorByInterpolatingForBarTintWithMinimumAlpha: (CGFloat) alpha
{
    NSAssert(self.canProvideRGBComponents, @"Self must be a RGB color to use arithmatic operations");
    NSAssert(self.alpha == 1, @"Self must be an opaque RGB color");

    CGFloat r, g, b, a;
    if (![self getRed:&r green:&g blue:&b alpha:&a]) return nil;

    CGFloat r2,g2,b2,a2;
    r2 = g2 = b2 = a2 = 1;

    CGFloat red,green,blue;

    alpha -= 0.01;
    do {
        alpha += 0.01;
        red = (r - r2 + r2 * alpha) / alpha;
        green = (g - g2 + g2 * alpha) / alpha;
        blue = (b - b2 + b2 * alpha) / alpha;
    } while (alpha < 1 && (red < 0 || green < 0 || blue < 0 || red > 1 || green > 1 || blue > 1));

    UIColor *new = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
    return new;
}

Если у кого-то есть более элегантный способ вычисления альфа (я съеживаюсь от этого цикла do-while), я бы хотел его увидеть: https://gist.github.com/sgtsquiggs/7206385

person Matthew Crenshaw    schedule 28.10.2013

Просто воспользуйтесь этим простым калькулятором barTintColor:

http://htmlpreview.github.io/?https://github.com/tparry/Miscellaneous/blob/master/UINavigationBar_UIColor_calculator.html.

введите описание изображения здесь

person Damien Romito    schedule 20.01.2015

Вот еще один способ получить правильный цвет полупрозрачной панели навигации в iOS 7.x и новее. Для некоторых цветов можно найти оптимальный цвет оттенка полосы, при котором полупрозрачная полоса будет отображаться с цветом, который соответствует желаемому.

Например, для цвета Facebook rgb: 65,96,156 или #41609c оптимальный цвет - #21458c. Следующий код устанавливает для всех панелей навигации в приложении цвет Facebook только с собственным API-интерфейсом какао:

UIColor* barColor = [UIColor colorWithRed:0.129995 green:0.273324 blue:0.549711 alpha:1.0]; // #21458c to make bars actual color match the #41609c color.
[[UINavigationBar appearance] setBarTintColor:barColor];

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

Я создал утилиту BarTintColorOptimizer, которую следует запустить на устройстве для поиска оптимизированного цвета полосы для любого цвета, который вы вводите. .

person IvanRublev    schedule 24.11.2015
comment
BarTintColorOptimizer великолепен! - person Gamec; 01.02.2018
comment
Спустя почти пять лет этот недооцененный ответ по-прежнему является единственно правильным решением (поскольку любое решение этой проблемы является правильным). Удивительно, что советы Apple по этому поводу сводятся к тому, чтобы понять это самостоятельно. Спасибо, что написали BarTintColorOptimizer! - person sizzle beam; 29.09.2020

Я полагаю, вы прочитали все комментарии выше. Если вы хотите получить настраиваемый фон и прозрачность, вам следует переопределить класс панели навигации и реализовать свой собственный метод layoutubviews. Просто добавьте сюда дополнительное подвид. ВАЖНО: вы должны добавить его чуть выше фонового представления NavigationBar. Он скроет ваш заголовок или кнопки, если вы просто поместите его над всеми подпредставлениями.

Также ознакомьтесь с этим вопросом

person gleb.kudr    schedule 25.09.2013
comment
avishic предоставил именно такой подход за 1,5 дня до вашего ответа. Поправьте меня если я ошибаюсь... - person stk; 30.09.2013
comment
Не совсем то же самое. Он перемещает newSubview за все subviews на панели навигации. Но вы должны разместить его прямо над исходным фоном панели навигации, который остается последним подвидом. - person gleb.kudr; 30.09.2013

Простое / быстрое решение, которое сработало для меня. Просто установите оттенок полосы в раскадровке, а не на фоне.

Сначала выберите панель навигации в контроллере навигации
 Панель навигации

Затем щелкните инспектор атрибутов справа и установите оттенок полосы
Полосчатый оттенок

Вы можете выбрать предопределенный цвет или щелкнуть по цвету, чтобы установить для него другой цвет.
 введите описание изображения здесь

person Markymark    schedule 30.11.2016

Чтобы цвет оттенка выглядел темнее, вы можете изменить цвет фона панели навигации:

UIColor *color1 = [UIColor colorWithRed:55.0f/256.0f green:0.0f blue:1.0f alpha:1.0f];
[navBar setBarStyle:UIBarStyleBlackTranslucent];
[navBar setBarTintColor:color1];
UIColor *color2 = [UIColor colorWithWhite:0 alpha:0.3];
[navBar setBackgroundColor:color2];

Попробуйте поиграть с color1 и color2, чтобы добиться подходящего вам результата. Все остальное будет бороться с фреймворком.

person Eugene Dudnyk    schedule 24.09.2013
comment
Это не работает, так как не покрывает область под строкой состояния, а также показывает градиент ближе к нижней части панели навигации. - person Ian Hoar; 04.10.2013

navBar.barTintColor = [UIColor orangeColor];
navBar.translucent = YES;
UIColor *backgroundLayerColor = [[UIColor redColor] colorWithAlphaComponent:0.7f];
static CGFloat kStatusBarHeight = 20;

CALayer *navBackgroundLayer = [CALayer layer];
navBackgroundLayer.backgroundColor = [backgroundLayerColor CGColor];
navBackgroundLayer.frame = CGRectMake(0, -kStatusBarHeight, navBar.frame.size.width,
        kStatusBarHeight + navBar.frame.size.height);
[navBar.layer addSublayer:navBackgroundLayer];
// move the layer behind the navBar
navBackgroundLayer.zPosition = -1;

Обратите внимание, что вам все равно придется поработать с barTintColor и backgroundLayerColor, чтобы получить точный цвет, который вы хотите. Кроме того, конечно, цвета зависят от цвета фона вашего представления контента (например, белого).

person bobics    schedule 24.09.2013

Я расширил UINavigationController,
на его viewDidLoad, добавил фон с таким же цветом оттенка.

Кроме того, я установил фоновую рамку, чтобы закрыть область строки состояния:

    self.navigationBar.barTintColor = navBackgroundColor;
    CGRect bgFrame = self.navigationBar.bounds;
    bgFrame.origin.y -= 20.0;
    bgFrame.size.height += 20.0;
    UIView *backgroundView = [[UIView alloc] initWithFrame:bgFrame];
    backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    backgroundView.backgroundColor = navBackgroundColor;
    backgroundView.alpha = 0.6;
    [self.navigationBar addSubview:backgroundView];
    [self.navigationBar sendSubviewToBack:backgroundView];

В моем случае альфа 0.6 справилась со своей задачей, но с ней можно поиграть.

person avishic    schedule 24.09.2013
comment
Кнопка "Назад" в нажатом контроллере просмотра перестает работать у меня с этим кодом, хотя "Готово" работает нормально. - person Nik; 25.09.2013
comment
Решил эту проблему, используя метод, описанный в stackoverflow.com/questions/3046813/ - person Nik; 25.09.2013
comment
Вы должны добавить свое subview чуть выше фонового представления NavigationBar. И с кнопками назад все будет хорошо. - person gleb.kudr; 25.09.2013

Если вы используете Swift 2.0, вы можете использовать это, это удалит размытие и цвет будет отображаться правильно.

UINavigationBar.appearance().translucent = false
person icekomo    schedule 03.02.2016
comment
Это приведет к сплошному цвету полосы, чего ОП специально не хотел. - person Michael Peterson; 21.03.2016

Сравнивая мои цвета до и после, я обнаружил, что насыщенность снизилась на 21%, в то время как оттенок и яркость остались прежними.

Добавив 21% обратно, я смог значительно улучшить соответствие цветов. К сожалению, наш цвет изначально имел насыщенность выше 80, поэтому увеличение значения выше 100% приводило к уменьшению отдачи и не соответствовало идеально, но стало намного ближе.

Для цветов с насыщенностью ниже 80 он должен работать еще лучше.

Для получения информации о том, как настроить насыщенность вашего цвета Как можно Я изменяю оттенок, яркость и насыщенность UIColor?

person SuperGuyAbe    schedule 30.03.2017

Вы можете запустить приложение в симуляторе и выбрать цвет панели навигации с помощью инструмента «Пипетка».

введите здесь описание изображения

person Vladimir    schedule 11.07.2017

Я много огляделся, и ни один из них на самом деле не сработал для меня, решение заключается в следующем:

1. Установите для навигации barTintColor (фон).

2- Запустите симулятор и откройте свое приложение, на вашем Mac откройте Цифровой измеритель цвета и выберите раскрывающийся список «Отображать в стандартном RGB».

введите здесь описание изображения

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

4- Перейдите в раскадровку, затем выберите цвет фона и убедитесь, что он на слайдерах RGB, и введите цвет здесь, вы получите тот же цвет, что и панель навигации.

введите здесь описание изображения

Примечание. не имеет значения, включен ли isTranslucent или нет.

Надеюсь, что это помогает вам.

person AaoIi    schedule 02.06.2019

Это должно работать:

UIColor *barColour = [UIColor colorWithRed:0.13f green:0.14f blue:0.15f alpha:1.00f];

UIView *colourView = [[UIView alloc] initWithFrame:CGRectMake(0.f, -20.f, 320.f, 64.f)];
colourView.opaque = NO;
colourView.alpha = .7f;
colourView.backgroundColor = barColour;

self.navigationBar.barTintColor = barColour;

[self.navigationBar.layer insertSublayer:colourView.layer atIndex:1];

Взято из здесь

person Scott Berrevoets    schedule 20.09.2013
comment
Это работает, только если у вас нет заголовка в панели навигации. Если у вас есть набор заголовков, он затемняется colorView. - person stk; 20.09.2013
comment
Этот код оставляет слой панели навигации соответствующим для z-порядка и фрейма для дальнейших настроек созданного вами слоя. В принципе плохой подход. Чтобы пойти по этому пути, вам нужно создать подкласс панели навигации для правильной работы с подпредставлениями на панели навигации, переопределив его метод layoutSubviews. - person Eugene Dudnyk; 24.09.2013

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

CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, -20,navigationBar.frame.size.width,navigationBar.frame.size.height + 20);
layer.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.75].CGColor;
layer.zPosition = -5;
[navigationBar.layer addSublayer:layer];
person user1007895    schedule 27.09.2013
comment
Вы читали другие ответы? Подход «добавление слоя в панель навигации» был опубликован как минимум дважды перед вашим ответом. - person stk; 30.09.2013

Это происходит потому, что navigationBar.translucent == YES. Установите для этого свойства значение NO, и это будет правильный цвет. Однако я не узнал, как применить этот полупрозрачный параметр ко всем панелям навигации, не вызывая его явно для каждой. При этом строка состояния также остается того же цвета, что и панель навигации.

person user1529956    schedule 22.09.2013
comment
Извините, но я четко заявил, что мне нужно, чтобы планка была полупрозрачной. - person stk; 23.09.2013
comment
Facebook тоже не является полупрозрачным. Что заставляет вас так говорить? Если вы хотите, чтобы полоса была полупрозрачной, нет никакого способа получить истинный цвет, так как у нее будет альфа ‹0 - person user1529956; 23.09.2013
comment
Просто прокрутите изображение под панелью навигации, и вы увидите, что оно полупрозрачное. - person stk; 23.09.2013
comment
Панель Facebook полупрозрачная. Устали от людей с iPhone 4, говорящих всем, что панель Facebook - нет, хотя это явно так. - person Leo Natan; 24.09.2013
comment
У меня iPhone 5, и на моем он не полупрозрачен. Не уверен, почему это отличается. - person user1529956; 24.09.2013
comment
Извините, я хотел сказать альфа ‹1 в другом посте. Это все равно, что установить любой цвет альфа (где угодно) на ‹1, а затем сказать:« Почему цвет не такой, как когда альфа = 1. - person user1529956; 24.09.2013
comment
О, моя ошибка, он явно полупрозрачный, но незаметно. - person user1529956; 24.09.2013

Попробуйте отрендерить соответствующее фоновое изображение для панели навигации. Это сработало для моего тестового приложения.

UIGraphicsBeginImageContext(CGSizeMake(1, 1));
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor colorWithRed:55.0f/256.0f green:0.0f blue:1.0f alpha:0.5f] set];
CGContextFillRect(context, CGRectMake(0, 0, 1, 1));

UIImage *navBarBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[[UINavigationBar appearance] setBackgroundImage:navBarBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:navBarBackgroundImage forBarMetrics:UIBarMetricsLandscapePhone];
person Eugene Dudnyk    schedule 23.09.2013
comment
В результате получается прозрачная, но не полупрозрачная панель навигации. en.wikipedia.org/wiki/Transparency_and_translucency - person stk; 23.09.2013
comment
Хорошо, затем заполните отчет об ошибке Apple и попросите дизайнеров предоставить правильное фоновое изображение, если прозрачность, предоставляемая системой, вам не подходит. - person Eugene Dudnyk; 24.09.2013
comment
Извините, но я только получаю прозрачность от вашего подхода. Никакого размытого эффекта нет. Translucency (на языке Apple) наследует эффект размытия, как у NavigationBar и т. Д., Когда вы устанавливаете navigationBar.translucent = YES; - person stk; 24.09.2013
comment
Эй, мужик, ты жестоко ставишь -1 на мой пост. Это полностью правильно, а прозрачность - частичный случай полупрозрачности. Если вам надоели бесполезные ответы, это сообщество не для вас. - person Eugene Dudnyk; 30.09.2013