Uzyskaj odpowiedni kolor w półprzezroczystym pasku nawigacyjnym iOS7

Jak mogę uzyskać odpowiednią kolorystykę dla moich przezroczystych pasków nawigacyjnych w iOS 7? Pasek nawigacyjny po prostu dostosowuje dany kolor do znacznie jaśniejszego. Zmiana jasności lub nasycenia koloru również nie zapewnia właściwego wyniku.

Ktoś ma ten sam problem? Wygląda na to, że jakoś działa, patrząc na Facebook: mają swoje kolory i półprzezroczyste paski nawigacyjne.

Edit: żeby było jasne: pasek musi być przezroczysty, a nie przezroczysty (z niektórymi alfa), nie stałe! http://en.wikipedia.org/wiki/Transparency_and_translucency

Edit: now posted to Apple BugReporter

Author: stk, 2013-09-19

19 answers

Pasek dostosuje wartości kolorów.

preferowana metoda, tylko dla RGB >= 40, da najwięcej rozmycia

Możesz użyć tego kalkulatora i umieścić w tym, jaki kolor ma być po renderowaniu na ekranie, powie Ci, co ustawić kolor barintcolor, więc gdy Apple go dostosuje, wyświetli się zgodnie z przeznaczeniem

Http://b2cloud.com.au/how-to-guides/bar-color-calculator-for-ios7-and-ios8/

Edit: zauważ, że te obliczenia są dla białego tła i dla jaśniejszych kolorów (RGB powyżej 40, jeśli potrzebujesz ciemniejszego, musisz dodać warstwę tła, jak inni wspominali - chociaż zmniejszy to rozmycie paska) {]}

alternatywny ciemny widok podkładu, przykład z ciemnoniebieskim kolorem Facebook: (65,96,156) http://img707.imageshack.us/img707/3151/482w.png

[[3]}in depth guide: http://b2cloud.com.au/how-to-guides/custom-uinavigationbar-colors-in-ios7

Fragment:

@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]];
 80
Author: SomeGuy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-25 14:30:22

Wystarczy zmienić translucent Właściwość

navigationBar.translucent = NO;

Jest to skutecznie to samo, co usuwanie / tworzenie przezroczystych podwarstw/podwarstw paska nawigacyjnego.

 14
Author: malex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-19 09:20:55

Poprawiłem kod z osiągając jasne, żywe kolory dla przezroczystego UINavigationBar iOS 7 w moim forku: https://github.com/allenhsu/CRNavigationController

Z moją modyfikacją, wynik kolor na ekranie (wybrany na białym tle) będzie dokładnie taka sama wartość przekazywana do setBarTintColor. Myślę, że to niesamowite rozwiązanie.

 4
Author: Allen Hsu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:34

Wiem, że ta odpowiedź jest trochę spóźniona, ale jeśli używasz Kreatora interfejsu, możesz uzyskać niewłaściwy kolor podczas używania wartości szesnastkowej, ponieważ Kreator interfejsu jest ustawiony na użycie niewłaściwej przestrzeni kolorów. W Xcode 6.4 możesz nacisnąć mały bieg w prawym górnym rogu okna dialogowego próbnika kolorów, aby wybrać używaną przestrzeń kolorów:

Tutaj wpisz opis obrazka

Mój został ustawiony na sRGB IEC6196-2.1, kiedy właściwie powinienem był używać generycznego RGB.

 3
Author: Elethier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-17 20:05:03

Jeśli twój kolor nie jest wyjątkowo żywy, możesz obliczyć równoważny kolor w / alpha. Działa to dobrze w systemie iOS 7.0.3+; przed 7.0.3 automatycznie zastosował 0.5 alpha.

Ten kod zakłada, że kolor wejściowy jest RGB i nieprzezroczysty, a kolor tła jest biały:

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

Jeśli ktoś ma bardziej elegancki sposób obliczania Alfy (ja się przy tym kręcę pętlą do-while) to chętnie go zobaczę: https://gist.github.com/sgtsquiggs/7206385

 2
Author: Matthew Crenshaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-28 23:17:28

Przypuszczam, że przeczytałeś wszystkie komentarze powyżej. Jeśli chcesz uzyskać własne tło i przezroczystość, powinieneś nadpisać klasę navigationbar i zaimplementować własną metodę layoutsubview. Proste dodawanie dodatkowego podglądu tutaj. Ważne: powinieneś dodać go tuż nad podkategorią tła paska nawigacyjnego. Ukryje nagłówek lub przyciski, jeśli umieścisz je nad wszystkimi podwidywami.

Sprawdź również to pytanie

 1
Author: gleb.kudr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:52
 1
Author: Damien Romito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-20 17:14:36

Oto inny sposób na uzyskanie odpowiedniego koloru półprzezroczystego paska nawigacyjnego w systemie iOS 7.x i Później. W przypadku niektórych kolorów można znaleźć optymalny odcień paska, który sprawia, że półprzezroczysty pasek pojawia się z kolorem, który pasuje do pożądanego.

Na przykład dla koloru Facebook, który jest rgb: 65,96,156 lub #41609c optymalnym kolorem jest #21458c. Poniższy kod ustawia wszystkie paski nawigacyjne w aplikacji, aby były koloru Facebook z natywnym API cocoa-touch:

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

Jedynym ograniczeniem metoda polega na tym, że zoptymalizowany kolor nie może być znaleziony dla każdego możliwego koloru. Zazwyczaj nie jest to możliwe w przypadku ciemnych kolorów.

Zrobiłem BarTintColorOptimizer narzędzie, które powinno być uruchomione na urządzeniu, aby wyszukać zoptymalizowany kolor paska dla dowolnego wprowadzonego koloru.

 1
Author: IvanRublev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-24 17:44:25

Proste / szybkie rozwiązanie, które zadziałało dla mnie. Po prostu ustaw odcień paska w scenariuszu, a nie w tle.

Najpierw wybierz pasek nawigacji w kontrolerze nawigacji
Pasek Nawigacji

A następnie kliknij Inspektora atrybutów po prawej stronie, a następnie Ustaw Bar Tint
Bar tint

Możesz wybrać wstępnie zdefiniowany kolor lub kliknąć na kolor, aby ustawić go na coś innego.
Tutaj wpisz opis obrazka

 1
Author: Markymark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-30 06:48:13

Aby kolor tła był ciemniejszy, możesz zmienić kolor tła paska nawigacyjnego:

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

Spróbuj bawić się kolorami color1 i color2, aby osiągnąć wynik, który pasuje do ciebie. Wszystko inne byłoby walką z ramami.

 0
Author: DisableR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-24 09:15:54
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;

Uwaga, Aby uzyskać żądany kolor, nadal musisz używać kolorów barintcolor i backgroundLayerColor. Oczywiście kolory zależą również od koloru tła widoku zawartości (np. białego).

 0
Author: bobics,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-24 09:53:22

Rozszerzyłem UINavigationController,
na jego viewDidLoad dodałem tło o tym samym kolorze odcienia.

Ustawiłem również ramkę tła na obszar paska stanu:

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

W moim przypadku alpha 0.6 załatwiła sprawę, ale można się nią bawić.

 0
Author: avishic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-24 10:37:54

Jeśli używasz swift 2.0 możesz tego użyć, spowoduje to usunięcie rozmycia i poprawne wyświetlanie kolorów.

UINavigationBar.appearance().translucent = false
 0
Author: icekomo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 23:20:57

Porównując moje kolory przed i po odkryłem spadek nasycenia o 21%, podczas gdy barwa i jasność pozostały takie same.

Dodając 21% z powrotem udało mi się znacznie poprawić dopasowanie kolorów. Niestety nasz kolor miał nasycenie powyżej 80 na początek, więc pchanie go powyżej 100% miało malejące zwroty i nie pasowało idealnie, ale zbliżyło się znacznie.

Dla kolorów o nasyceniu poniżej 80 powinno być jeszcze lepiej.

Dla informacji jak dostosuj Nasycenie koloru Jak mogę zmodyfikować odcień, jasność i nasycenie Uicolora?

 0
Author: SuperGuyAbe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:55

Możesz uruchomić aplikację w symulatorze i pobrać kolor paska nawigacyjnego za pomocą narzędzia Kroplomierz.

Tutaj wpisz opis obrazka

 0
Author: Vladimir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 13:07:41

To powinno zadziałać:

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

Wzięte z tutaj

 -1
Author: Scott Berrevoets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-20 12:52:44

To działa dla mnie:

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];
 -2
Author: user1007895,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-27 20:16:08

Dzieje się tak, ponieważ pasek nawigacyjny.przezroczysty = = tak. Ustaw tę właściwość NA NO i będzie to prawidłowy kolor. Jednak nie dowiedziałem się, jak zastosować to półprzezroczyste ustawienie do wszystkich pasków nawigacyjnych bez wywoływania go jawnie na każdym. Pasek stanu pozostaje w tym samym kolorze co pasek nawigacji.

 -4
Author: user1529956,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-22 00:01:46

Spróbuj renderować odpowiedni obraz tła dla paska nawigacyjnego. To zadziałało na moją aplikację testową.

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];
 -4
Author: DisableR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-23 15:29:39