ios - translucent - uinavigationcontroller transparent




為iOS 7半透明UINavigationBar實現鮮豔生動的色彩 (11)

Theres是一個很好的Dropin UINavigationController替換軟件,可從GitHub的Simon Booth獲得這裡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;

iOS 7.1更新 :看起來修改UINavigationBar中的alpha通道的解決方法在此更新中被忽略。 現在,最好的解決辦法似乎是“處理它”,並希望你選擇的任何顏色都可以產生半透明的效果。 我仍在研究如何解決這個問題。

iOS 7.0.3更新我們創建GitHub庫已經更新,可以在使用iOS 7.0.3時稍微解決此問題。 不幸的是,沒有神奇的公式可以支持在iOS 7.0.2和更早版本以及iOS 7.0.3中創建的顏色。 似乎蘋果提高了飽和度,但代價是不透明度(因為模糊的半透明度取決於不透明度水平)。 我和其他一些人正在努力為此創建一個更好的解決方案。

我相信很多人已經遇到了iOS 7傾向於使UINavigationBar顏色變得半透明的問題。

我的目標是實現具有這種淺色但是半透明的UINavigationBar:

然而,透明,我得到了這個。 背景視圖是白色的,據我了解,這個視圖會變得更輕:

有沒有辦法在保持半透明的同時達到原有的色彩? 我注意到Facebook已經能夠讓他們的酒吧成為他們豐富的藍色,如下所示:

所以我知道必須有某種方式。 背景視圖顯然在這裡有所作為,但其大部分內容也是灰色/白色。 看起來,無論您穿什麼色調的色彩,都無法在半透明下獲得生動的色彩。

更新與解決方案。

這是我最終提出的解決方案。 我使用了aprato的解決方案,然後在UINavigationController子類中包含了自定義的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

tintColor for bars的行為在iOS 7.0上已更改。 它不再影響酒吧的背景,並像添加到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)

一種低保真方式可能會將UIView固定在導航欄的高度上,位於酒吧後面的視圖頂部。 使該視圖與導航欄顏色相同,但使用alpha直到獲得所需的效果:

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的alpha:

self.navigationController.navigationBar.alpha = 0.5f;

編輯:實際上,經過測試,似乎這不提供意圖行為(或任何行為):

.8 alpha

未經調整的阿爾法

顯然,你只會想在iOS 7設備上這樣做。 因此,在實現任何這些之前添加一些版本檢查


一種簡單的方法來獲得你想要的顏色正在使用

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

只要你的圖像有一些alpha,半透明就可以工作,你可以通過改變圖像來設置alpha。 這只是在iOS7中添加的。 垂直圖像的寬度和高度為640x88px(如果您希望它位於狀態欄下方,則將88添加到88)。


在iOS 7上嘗試設置透明度為DISABLED的統一顏色導航欄時,我遇到了這個問題。

在用barTintColor試驗了一段時間之後,我發現有一個不透明的導航欄的簡單方法是製作所需顏色的單個像素圖像,製作可伸縮圖像,並將其設置為導航欄的backgroundImage 。

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

三行代碼,非常簡單,適用於iOS 6和iOS 7(barTintColor在iOS 6上不受支持)。


在相關說明中,您可以通過以下方式輕鬆設置標題文字顏色(帶陰影):

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

我使用了@ aprato的解決方案,但發現了一些新的VC(例如UINavigationItemButtonViewsUINavigationItemViews等)的新層會自動插入到extraColorLayer下面的位置(這會導致這些標題或按鈕元素受到影響) extraColorLayer ,因此顏色比通常情況下變淡)。 所以我調整了@ aprato的解決方案,強制extraColorLayer停留在索引位置1.在索引位置1, extraColorLayer保持在_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
}


有沒有一種方法來使用@aprato解決方案,而不需要繼承UINavigationBar。

在我的項目中,我的主視圖是UIViewController。

問題是navigationController是只讀屬性,有沒有辦法使用你的類與我的項目,因為我不能使用: [[UINavigationController alloc] initWithNavigationBarClass:

謝謝


正如上面提到的 @bernhard ,可以使色條顏色飽和以獲得所需的導航欄外觀。

我為這種調整寫了一個BarTintColorOptimizer實用程序 。 它優化半透明條色的顏色,使條的實際顏色與iOS 7.x及更高版本中的所需顏色相匹配。 細節請看這個答案 。


這些攻擊都不需要:)。 簡單地設置:

self.navigationController.navigationBar.translucent = NO;

對於iOS 7,默認半透明度保持為TRUE。





ios7