1. ホーム
  2. ios

[解決済み] iOS 7の半透明なUINavigationBarで明るく鮮やかな色を実現するために

2022-04-23 18:01:36

質問


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を実現することです。

しかし、半透明化では、このようになってしまいます。背景のビューが白なので、このビューが少し明るくなるのは理解できるのですが。

透け感を出しながら、元の色を実現する方法はないのでしょうか?Facebookは、ここに表示されているように、バーを豊かな青色にすることができました。

...だから、何か方法があるはずだと思うんです。背景表示は明らかに違いがありますが、その内容もほとんどがグレー/白です。バーティントカラーをどのように入れても、半透明では鮮やかな色を得ることができないようです。

解決策を更新しました。

結局、私が思いついた解決策は以下の通りです。私は アプラート の解決策を包含し、さらにカスタムの 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

解決方法は?

iOS 7.0.3 アップデートを行いました。 上記の通り7.0.3ではいろいろと変わりました。gistを更新しました。うまくいけば、この問題は解決されるでしょう。

オリジナルの回答です。 結局、他の回答の2つを組み合わせたハックに行き着きました。私はUINavigationBarをサブクラス化し、様々な高さのステータスバーが表示されている場合にカバーするために、いくつかの余分なスペースを持つ背面にレイヤーを追加しています。レイヤーはレイアウトサブビューで調整され、色はbarTintColorを設定するたびに変更されます。

Gist: 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;

レイアウトサブビュー

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