iOS 7 반투명 UINavigationBar를위한 밝고 생생한 색상 달성


172

iOS 7.1 업데이트 : UINavigationBar에서 알파 채널을 수정하는 해결 방법이이 업데이트에서 무시 된 것 같습니다. 지금 가장 좋은 해결책은 '그것을 다루는 것'이며, 원하는 색상이 반투명 효과를 낼 수 있기를 바랍니다. 나는 아직도이 문제를 해결하는 방법을 찾고 있습니다.


iOS 7.0.3 업데이트 : 우리가 만든 GitHub 라이브러리가 iOS 7.0.3을 사용할 때이 문제를 약간 해결하도록 업데이트되었습니다. 불행히도 iOS 7.0.2 및 이전 버전과 iOS 7.0.3에서 생성 된 두 가지 색상을 모두 지원하는 마법 공식은 없습니다. Apple이 채도를 개선 한 것처럼 보이지만 불투명도는 떨어집니다 (흐린 반투명도는 불투명도 수준에 의존하기 때문에). 나는 다른 사람들과 함께 이것에 대한 훨씬 더 나은 수정을 위해 노력하고 있습니다.


나는 많은 사람들이 이미 iOS 7이 반투명 UINavigationBar의 색상을 채도가 떨어지는 문제에 직면했다고 확신합니다.

내 목표는이 색조 색상으로 UINavigationBar를 달성하는 것이지만 반투명합니다.

UINavigationBar, 불투명

그러나 반투명으로, 나는 이것을 얻고 있습니다. 배경보기는 흰색 이므로이보기를 조금 더 밝게 만듭니다.

반투명 UINavigationBar

반투명도를 유지하면서 원래 색상을 얻을 수있는 방법이 있습니까? Facebook이 다음과 같이 막대가 풍부하고 푸른 색이 될 수 있음을 알았습니다.

Facebook UINavigationBar, 반투명

.. 그래서 어떤 방법이 있어야한다는 것을 알고 있습니다. 백그라운드 뷰는 여기에서 분명히 차이를 만들지 만 대부분의 내용은 회색 / 흰색입니다. 바 색조 색상에 관계없이 반투명 상태에서 선명한 색상을 얻을 수없는 것 같습니다.

솔루션으로 업데이트되었습니다.

여기에 내가 찾은 해결책이 있습니다. 나는 aprato 의 솔루션을 취한 다음 하위 클래스 UINavigationBar내 에서 사용자 정의를 포함했습니다 UINavigationController. 아래에이 구현이있는 리포지토리와 예제 app을 만들었습니다 .

////////////////////////////
// CRNavigationBar.m
////////////////////////////

#import "CRNavigationBar.h"

@interface CRNavigationBar ()
@property (nonatomic, strong) CALayer *colorLayer;
@end

@implementation CRNavigationBar

static CGFloat const kDefaultColorLayerOpacity = 0.5f;
static CGFloat const kSpaceToCoverStatusBars = 20.0f;

- (void)setBarTintColor:(UIColor *)barTintColor {
    [super setBarTintColor:barTintColor];
    if (self.colorLayer == nil) {
        self.colorLayer = [CALayer layer];
        self.colorLayer.opacity = kDefaultColorLayerOpacity;
        [self.layer addSublayer:self.colorLayer];
    }
    self.colorLayer.backgroundColor = barTintColor.CGColor;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    if (self.colorLayer != nil) {
        self.colorLayer.frame = CGRectMake(0, 0 - kSpaceToCoverStatusBars, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + kSpaceToCoverStatusBars);

        [self.layer insertSublayer:self.colorLayer atIndex:1];
    }
}

@end

////////////////////////////
// CRNavigationController.m
////////////////////////////

#import "CRNavigationController.h"
#import "CRNavigationBar.h"

@interface CRNavigationController ()

@end

@implementation CRNavigationController

- (id)init {
    self = [super initWithNavigationBarClass:[CRNavigationBar class] toolbarClass:nil];
    if(self) {
        // Custom initialization here, if needed.    
    }
    return self;
}

- (id)initWithRootViewController:(UIViewController *)rootViewController {
    self = [super initWithNavigationBarClass:[CRNavigationBar class] toolbarClass:nil];
    if(self) {
        self.viewControllers = @[rootViewController];
    }

    return self;
}

@end

Facebook iOS7 UINAvigationBar입니까?
Vinzzz

아니, 기본 iOS보다 훨씬 더 투명합니다. 훨씬 좋습니다.
케빈

Facebook NavigationBar 투명하지 않음
LE SANG

7
확실히 반투명합니다. 편집 한 답변을 참조하십시오.
SpacePyro

2
@Odelya-이것은 올바른 색상을 얻는 솔루션이 아니라 UINavigationBariOS 7에서 반투명에 노출되었을 때 가능한 최상의 밝기를 보정하는 솔루션입니다 .
SpacePyro

답변:


52

iOS 7.0.3 업데이트 : 위에서 보듯이 7.0.3에서 변경된 사항이 있습니다. 요점을 업데이트했습니다. 사람들이 업그레이드함에 따라 이것은 사라질 것입니다.

독창적 인 답변 : 나는 다른 두 가지 답변을 결합한 핵으로 끝났습니다. UINavigationBar를 서브 클래스 화하고 다양한 높이 상태 표시 줄이 위로 올라가면 덮을 공간이있는 뒤에 레이어를 추가합니다. 레이아웃 하위 뷰에서 레이어가 조정되고 barTintColor를 설정할 때마다 색상이 변경됩니다.

요점 : https://gist.github.com/aprato/6631390

setBarTintColor

  [super setBarTintColor:barTintColor];
  if (self.extraColorLayer == nil) {
    self.extraColorLayer = [CALayer layer];
    self.extraColorLayer.opacity = self.extraColorLayerOpacity;
    [self.layer addSublayer:self.extraColorLayer];
  }
  self.extraColorLayer.backgroundColor = barTintColor.CGColor;

layoutSubviews

  [super layoutSubviews];
  if (self.extraColorLayer != nil) {
    [self.extraColorLayer removeFromSuperlayer];
    self.extraColorLayer.opacity = self.extraColorLayerOpacity;
    [self.layer insertSublayer:self.extraColorLayer atIndex:1];
    CGFloat spaceAboveBar = self.frame.origin.y;
    self.extraColorLayer.frame = CGRectMake(0, 0 - spaceAboveBar, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + spaceAboveBar);
  }

ViewController에서 이것을 어디서 구현 했습니까? viewDidLoad?
Jeremy

이것은 아름답게 작동합니다! 나는 이것을 내 UINavigationController서브 클래스 에 추가하기로 결정했다 . 다음 은 내에서 사용자 정의에 관심이있는 사람들을위한 요점 입니다 . UINavigationBarUINavigationController
SpacePyro

SpacePyro와 같은 @Jeremy 나는 initWithRootViewController이것을 사용하기 위해 재정의하는 네비게이션 컨트롤러 서브 클래스 (UIAppearance 타겟팅을 위해 pre 7을 사용했던 바와 같은)를 가지고 있습니다 . 요점을 업데이트했습니다
Anthony

음… 좋아요. 전체 테스트 프로젝트에서이 내용을 확인해야합니다. 아래에서 timeuser의 예제를 복제 할 수 있었지만 여전히이 예제에서는 약간 녹색입니다.
Jeremy Jeremy

1
@ Mr.T 감사합니다! 내가 작성했을 때 그것은 아직 추진되지 않았습니다 :) 그러나 지금 업데이트했습니다. 불투명도에 대한 UIAppearance를 추가하고 NSCoding에 대한 지원
Anthony

10

iOS 7.0에서 막대의 tintColor 동작이 변경되었습니다. 더 이상 막대의 배경에 영향을 미치지 않으며 UIView에 추가 된 tintColor 속성에 대해 설명 된대로 작동합니다. 막대의 배경을 색조로 지정하려면 -barTintColor를 사용하십시오. 다음 코드를 사용하여 ios6 및 ios7 둘 다에서 앱이 작동하도록 할 수 있습니다.

if(IS_IOS7)
{
    self.navigationController.navigationBar.barTintColor = [UIColor blackColor];
    self.navigationController.navigationBar.translucent = NO;
}
else
{
    self.navigationController.navigationBar.tintColor = [UIColor blackColor];
}

IS_IOS7은 다음과 같이 pch 파일에 정의 된 매크로입니다.

#define IS_IOS7 ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0)

9

나는이 솔루션을 생각해 냈지만 꽤 잘 작동하는 것 같습니다. 방금 UINavigationController의 하위 클래스에서 viewDidLoad에 추가했습니다.

출처 : https://gist.github.com/alanzeino/6619253

// cheers to @stroughtonsmith for helping out with this one

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

1
새 View Controller를 Navigation 컨트롤러로 푸시하면 모든 막대 버튼 항목이이 투명도 레이어 아래로 이동합니다.
Evan Davis

이 투명도 레이어로 인해 제목이 가려집니다.
Nick Locking

나는이 요점을 썼다. 의견이 맞습니다. 새 뷰 컨트롤러를 누를 때 버튼 항목이 아래로 밀리거나 하위 레이어가의 알파를 상속합니다 colourView. 나는 다른 대답을 포크와 새로운 드롭 인 (drop-in) 클래스로 몇 가지 고정 : github.com/alanzeino/AZColoredNavigationBar
앨런 Zeino

반투명 검은 색 탐색 막대 스타일을 선택하여 텍스트를 흰색으로 표시 할 수있었습니다. 또한 yourBar.tintColor = [UIColor whiteColor]; 상단에 다른 사용자 정의 버튼이 있습니다.
Juan Zamora

6

저해상도 방법 중 하나 UIView는 탐색 막대의 높이를 막대 뒤의보기 상단에 고정시키는 것일 수 있습니다 . 해당보기를 탐색 막대와 동일한 색상으로 만들지 만 원하는 효과를 얻을 때까지 알파로 재생하십시오.

UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.navigationController.navigationBar.frame), 64)];
    backgroundView.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:1 alpha:.5];

[self.navigationController.view insertSubview:backgroundView belowSubview:self.navigationController.navigationBar];

UIView 뒤

여기에 이미지 설명을 입력하십시오

(낮은 예에서 투명도를 강조하기 위해 색상을 변경했습니다. 이동시 투명도 / 흐림이 더 두드러집니다.)

서브 클래 싱하고 UINavigationBar동일한 뷰를 배경 위에 배치하지만 다른 모든 것 뒤에 배치하면 해키가 덜되는 동안 비슷한 결과를 얻을 수 있습니다.


내가 던져 본 또 다른 해결책은의 알파를 가지고 노는 것입니다 UINavigationBar.

self.navigationController.navigationBar.alpha = 0.5f;

편집 : 실제로 테스트 후 의도 한 동작 (또는 모든 동작)을 제공하지 않는 것 같습니다.

0.8 알파

0.8 알파의 탐색 모음

조정되지 않은 알파

여기에 이미지 설명을 입력하십시오

분명히, 당신은 iOS 7 장치에서만 이것을 원할 것입니다. 따라서 이들 중 하나를 구현하기 전에 버전 확인을 추가하십시오 .


나는 당신이 찾고있는 색상을 얻기 위해 알파와 tintColor를 업데이트하는 접근법을 두 번째로 사용합니다.
StuartM

덜 침습적 인 방법으로 원하는 효과를 얻을 수 있다면 완전히하십시오. 그러나 그것이 얼마나 효과적인지 잘 모르겠습니다.
케빈

내가 가지고있는 유일한 문제는 사진에 표시되지 않는 것입니다. 탐색 모음 위에 직접보기를 추가하고 결과적으로 컨트롤이 차단 된다는 것입니다. / image / 3d3C2o0N283S
SpacePyro

으아 아 아아아 아아아 되어야합니다[self.navigationController.view insertSubview:backgroundView belowSubview:self.navigationController.navigationBar];
Kevin

그래, 그게 니가 의미 한 것 같아 ;) 이것은 분명히 나에게 더 나은 색상 범위를 제공합니다. 흐림 효과가 여전히 그 아래의 모든 것을 채도 감소 시킨다는 점을 고려하면 원래 색상의 생동감을 얻는 것은 아마도 불가능할 것입니다. 지금은 더 어두운 색으로 살아야합니다.
SpacePyro

4

RGB 형식으로 UIColor 객체를 만드는 대신 HSB를 사용 하고 채도 매개 변수를 늘리십시오. (크레딧 샘 Soffes는 사람이 방법을 설명합니다 여기 )

navigationBar.barTintColor = [UIColor colorWithHue:0.555f saturation:1.f brightness:0.855f alpha:1.f];

참고 :이 솔루션은 트레이드 오프이며 채도가 높은 색상에는 적합하지 않습니다.

디자인에서 HSB 색상을 선택하려면 ColorSnapper 와 같은 도구 를 사용하여 UIColor HSB 형식을 간단히 복사 할 수 있습니다.

David Keegan 의 UIColor 카테고리 ( GitHub 링크 )를 사용 하여 기존 색상을 수정할 수도 있습니다.


3

Apple은 새로운 7.0.3 릴리스에서이 문제를 해결했습니다.


1
예. 색조 색상 구현이 7.0.3에서 확실히 변경되었습니다. 이제 채도를 10-15 % 정도 높이면 원하는 색상을 얻을 수 있습니다. 추가 레이어를 광고하기 전에.
Matej Bukovinski

알려 줘서 고마워! 이를 위해 라이브러리에 대한 업데이트를 추진할 것입니다.
SpacePyro

1
7.1> _ <에서 수정되지
않음

1

나는 새로운 벤처 캐피탈에서 새 레이어 (예. 몇 코너 케이스 aprato의 솔루션 @ 사용하지만, 발견 UINavigationItemButtonViews, UINavigationItemViews등) 자동으로 아래 위치에 삽입 될 extraColorLayer그 제목이나 버튼 요소에 의해 영향을받을 발생할 것이다 ( extraColorLayer따라서를 평상시보다 색이 희미합니다). 그래서 @aprato의 솔루션을 조정 extraColorLayer하여 인덱스 위치 1을 extraColorLayer유지했습니다 . 인덱스 위치 1에서 _UINavigationBarBackground.

내 클래스 구현은 다음과 같습니다.

- (void)setBarTintColor:(UIColor *)barTintColor
{
    [super setBarTintColor:barTintColor];
    if (self.extraColorLayer == nil)
    {
        self.extraColorLayer = [CALayer layer];
        self.extraColorLayer.opacity = kDefaultColorLayerOpacity;
        [self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
    }
    self.extraColorLayer.backgroundColor = barTintColor.CGColor;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    if (self.extraColorLayer != nil)
    {
        self.extraColorLayer.frame = CGRectMake(0, 0 - kSpaceToCoverStatusBars, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + kSpaceToCoverStatusBars);
    }
}

- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
{
    [super insertSubview:view aboveSubview:siblingSubview];
    [self.extraColorLayer removeFromSuperlayer];
    [self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}

- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index
{
    [super insertSubview:view atIndex:index];
    [self.extraColorLayer removeFromSuperlayer];
    [self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}

- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview
{
    [super insertSubview:view belowSubview:siblingSubview];
    [self.extraColorLayer removeFromSuperlayer];
    [self.layer insertSublayer:self.extraColorLayer atIndex:1]; // This way the text comes out clear
}

레이어와 서브 뷰가 혼합되어 있지 않기 때문에 addSubView를 오버로드 할 필요가 없습니다
Rob van der Veer


0

이러한 핵은 필요하지 않습니다 :). 간단히 설정하십시오.

self.navigationController.navigationBar.translucent = NO;

iOS 7의 경우 기본 반투명도가 TRUE로 유지되었습니다.


17
그러나이 질문에는 반투명도 필요합니다.
레오 나탄

:) 고마워, 그것은 나를 위해 일했다. 그러나 탐색 모음 아래에 1px 검은 색 아래쪽 테두리가 있습니다. 그것을 제거하는 방법이 있습니까?
Pritesh Desai

0

관련 메모에서 다음을 통해 제목 텍스트 색상 (그림자 포함)을 쉽게 설정할 수 있습니다.

NSShadow *titleShadow = [[NSShadow alloc] init];
titleShadow.shadowOffset = CGSizeMake(0.0f, -1.0f);
titleShadow.shadowColor = [UIColor blackColor];
NSDictionary *navbarTitleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor],
                                            NSShadowAttributeName: titleShadow};
[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];

1
iOS 7의 스타일과 일치 시키려면 제목 텍스트에 그림자를 사용하는 것이 부적절 할 수 있습니다.
Nick Locking

iOS 7에서 Apple은 더 이상 탐색 표시 줄 텍스트에 그림자를 설정하지 않습니다. 그러나 사용자 정의 모양을 원한다면 옵션이 제공됩니다.
bryguy1300

0

iOS 7에서 투명도가 비활성화 된 균일 한 색상의 탐색 막대를 설정하려고 하면서이 Q / A를 발견했습니다.

barTintColor를 사용하여 잠시 실험 한 후에 불투명 탐색 막대를 사용하는 가장 쉬운 방법은 원하는 색상의 단일 픽셀 이미지를 만들고 확장 가능한 이미지를 만들고 배경으로 설정하는 것입니다. .

UIImage *singlePixelImage = [UIImage imageNamed:@"singlePixel.png"];
UIImage *resizableImage = [singlePixelImage resizableImageWithCapInsets:UIEdgeInsetsZero];
[navigationBar setBackgroundImage:resizableImage forBarMetrics:UIBarMetricsDefault]; 

세 줄의 코드는 매우 간단하며 iOS 6 및 iOS 7에서 모두 작동합니다 (iOS 6에서는 barTintColor가 지원되지 않음).


0

Simon Booth에서 제공하는 훌륭한 Dropin UINavigationController 대체품은 GitHub에서 제공됩니다. GitHub-C360NavigationBar

iOS6를 역으로 지원하는 경우 루트보기 컨트롤러를 다음과 같이 확인하십시오.

PatientListTableViewController * frontViewController = [[PatientListTableViewController alloc] init];

    UINavigationController *navViewController = [[UINavigationController alloc] initWithNavigationBarClass:[C360NavigationBar class] toolbarClass:nil];
if ([navViewController.view respondsToSelector:@selector(setTintColor:)]) {
    //iOS7
    [navViewController.view setTintColor:self.navBarTintColor];
    [[C360NavigationBar appearance] setItemTintColor:self.navBarItemTintColor];
} else {
    //iOS6
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO];
    navViewController.navigationBar.tintColor = self.navBarTintColor;
}
[navViewController pushViewController:frontViewController animated:NO];

self.window.rootViewController = navViewController;

내가 빠진 것이 아니라면이 라이브러리의 바는 반투명하지 않습니다.
Rivera


-1

솔직히 말하면, 위의 답변은 옳을 수도 있지만 다음과 같은 트릭이 매우 쉽게 나를 위해 일했습니다.

// this is complete 100% transparent image
self.imageBlack = [[UIImage imageNamed:@"0102_BlackNavBG"] 
           resizableImageWithCapInsets:UIEdgeInsetsMake(0, 2, 0, 2)  
                          resizingMode:UIImageResizingModeStretch];

// this is non-transparent but iOS7 
// will by default make it transparent (if translucent is set to YES)
self.imageRed = [[UIImage imageNamed:@"0102_RedNavBG"] 
         resizableImageWithCapInsets:UIEdgeInsetsMake(0, 2, 0, 2)  
                        resizingMode:UIImageResizingModeStretch];

// some navigation controller
[nvCtrLeft.navigationBar setBackgroundImage:self.imageRed 
                              forBarMetrics:UIBarMetricsDefault];

// some another navigation controller
[nvCtrCenter.navigationBar setBackgroundImage:self.imageRed 
                                forBarMetrics:UIBarMetricsDefault];

self.imageRed및에 사용 된 이미지는 다음과 같습니다 self.imageBlack.

< self.imageBlack>이 괄호 안에있는 검은 색 이미지는 투명하므로 보이지 않습니다. :)

< self.imageRed> 빨간색 이미지가이 괄호 안에 있습니다.


이것은 흐려지지 않습니다.
Ortwin Gentz

-1

UINavigationBar를 서브 클래스 화하지 않고 @aprato 솔루션을 사용하는 방법이 있습니까?

내 프로젝트에서 내 주요보기는 UIViewController입니다.

문제는 navigationController가 읽기 전용 속성이라는 것입니다. 사용할 수 없기 때문에 프로젝트에서 클래스를 사용하는 방법이 있습니까? [[UINavigationController alloc] initWithNavigationBarClass:

감사


당신은 당신의 포장 수 없습니다 UIViewController내부를 UINavigationController함께 [[[UINavigationController alloc] initWithRootViewController:<YourViewController>]? 여기에 게시하는 대신 별도의 질문으로 답변하는 것이 좋습니다.
SpacePyro

-2

원하는 색상을 얻는 쉬운 방법은

    [<NAVIGATION_BAR> setBackgroundImage:<UIIMAGE> forBarPosition:<UIBARPOSITION> barMetrics:<UIBARMETRICS>];

이미지에 알파가있는 한 반투명도가 작동하며 이미지를 변경하여 알파를 설정할 수 있습니다. 이것은 iOS7에서 추가되었습니다. 이미지의 너비와 높이는 세로로 640x88 픽셀입니다 (상태 표시 줄 아래에 놓으려면 88에 20을 더하십시오).


그러나 이것은 흐릿함을 유지하지 않습니다. 투명도는 있지만 흐림은 없습니다.
레오 나탄
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.