iOS 7 の半透明 UINavigationBar で明るく鮮やかな色を実現する 質問する

iOS 7 の半透明 UINavigationBar で明るく鮮やかな色を実現する 質問する

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、半透明

..だから、何らかの方法があるはずだとわかっています。背景ビューは明らかに違いを生みますが、そのコンテンツのほとんどは灰色/白でもあります。バーの色合いに何を入れても、半透明の下では鮮やかな色が得られないようです。

解決策を更新しました。

これが私が最終的に思いついた解決策です。アプラトのソリューションを採用し、そのカスタムをサブクラスUINavigationBar内に組み込みましたUINavigationController以下にリストされているこの実装とサンプルアプリを含むリポジトリを作成しました。

////////////////////////////
// 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

ベストアンサー1

iOS 7.0.3 アップデート:ご覧のとおり、7.0.3 では変更点があります。gist を更新しました。アップグレードするにつれて、この問題は解消されると思います。

元の回答:最終的には、他の 2 つの回答を組み合わせたハックに落ち着きました。UINavigationBar をサブクラス化し、さまざまな高さのステータス バーのいずれかが表示されている場合に備えて、余分なスペースのあるレイヤーを背面に追加しています。レイヤーはレイアウト サブビューで調整され、barTintColor を設定するたびに色が変わります。

要旨:https://gist.github.com/aprato/6631390

バーの色を設定する

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

レイアウトサブビュー

  [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);
  }

おすすめ記事