ios 導航欄樣式設置

敘述

ios中導航欄是一個很頭疼的東西,由於navigationbar是統一設置,沒法實現每一個頁面有本身的導航欄樣式。解決的辦法有兩個,ios

一、隱藏系統自帶的self.navigationViewController.navigationBar,在baseViewController中本身添加一個navigationBar,這樣就能夠在每一個vc中設置本身的樣式了git

優勢:各管各的,不會相互影響,使用方便github

缺點:不會有過分漸變效果,每一個頁面都建立navigationBar,消耗稍微大點app

 

二、在vc出現的時候時(viewWillAppear)從新設置導航欄樣式ide

優勢:系統原生,效率高,可自定義導航欄過渡動畫效果函數

缺點:容易出坑動畫

 

-----------------------------凌亂分割線-----------------------------spa

接下來以第二種方法爲例,看看怎麼設置導航欄樣式:code

一、修改導航欄背景顏色

默認導航欄只有兩個樣式:黑色毛玻璃和白色毛玻璃orm

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

設置導航欄的顏色:

[self.navigationController.navigationBar setBarTintColor:[UIColor blueColor]];

因爲模式緣由,會混上白色或者黑色矇蔽+背景高斯模糊效果,因此設置的意思未必是你想要的真正顏色,網上有些顏色轉換的方法,可是我試了都不是特別準,寫一個相對好點的

- (UIColor *)barColorTransitionWithColor:(UIColor *)color {
    
    CGFloat red, green, blue, alpha;
    [color getRed:&red green:&green blue:&blue alpha:&alpha];
    
    CGFloat opacity = 0.4;
    
    CGFloat minVal = MIN(MIN(red, green), blue);
    
    if ([self convertValue:minVal withOpacity:opacity] < 0) {
        opacity = [self minOpacityForValue:minVal];
    }
    
    red = [self convertValue:red withOpacity:opacity];
    green = [self convertValue:green withOpacity:opacity];
    blue = [self convertValue:blue withOpacity:opacity];
    
    red = MAX(MIN(1.0, red), 0);
    green = MAX(MIN(1.0, green), 0);
    blue = MAX(MIN(1.0, blue), 0);
    
    return [UIColor colorWithRed:red green:green blue:blue alpha:1.];
}

- (CGFloat)minOpacityForValue:(CGFloat)value
{
    return (0.4 - 0.4 * value) / (0.6 * value + 0.4);
}

- (CGFloat)convertValue:(CGFloat)value withOpacity:(CGFloat)opacity
{
    return 0.4 * value / opacity + 0.6 * value - 0.4 / opacity + 0.4;
}

2.設置導航欄透明度

直接設置navigationBar的alpha是什麼效果的,須要獲取到navigation的subview,這裏ios10的subview類名有所改變,因此要特殊處理

NSString *backgroundViewClass = @"_UINavigationBarBackground";
if (IOS10) {
    backgroundViewClass = @"_UIBarBackground";
}
for (UIView * subView in self.subviews) {
    if ([subView isKindOfClass:NSClassFromString(backgroundViewClass)]) {
        [self setOverlay:subView];
        return subView;
    }
}

設置這個subview的alpha就能達到導航欄的透明度,而不影響導航欄上面item

3.控制導航欄分割線

一樣能夠遍歷navbar的subview獲取到分割線的view進行控制

- (UIImageView *)yxBottomLine:(UIView *)view
{
    if ([view isKindOfClass:[UIImageView class]] &&
        view.bounds.size.height <= 1.0)
    {
        return (UIImageView *)view;
    }
    for (UIView *subView in view.subviews)
    {
        UIImageView *imageView = [self yxBottomLine:subView];
        if (imageView)
        {
            return imageView;
        }
    }
    return nil;
}

4.修改導航欄item顏色:

[self.navigationController.navigationBar setTintColor:color];

5.修改導航欄標題樣式:

NSDictionary *attributes=[NSDictionary dictionaryWithObjectsAndKeys:titleColor, NSForegroundColorAttributeName, [UIFont boldSystemFontOfSize:17], NSFontAttributeName, nil];
[self.navigationController.navgationBar setTitleTextAttributes:attributes];

6.添加導航欄過分漸變更畫:

[[self transitionCoordinator] animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
                                                                            [self updateNavigationBarType:type];
                                                                    } completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
                                                                        if (![context isCancelled]) {
                                                                            [self updateNavigationBarType:type];
                                                                        }
                                                                    }];

在導航欄樣式發送變化的時候放到這個函數裏來,ps:ios10過分動畫不理想,能夠ios10參考第一中方法實現

7.自定義導航欄返回按鈕圖標

- (void)updateNavBackItemIcon {
    [self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"icon_navigation_back"]];
    [self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"icon_navigation_back"]];
    [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes: @{NSFontAttributeName:[UIFont systemFontOfSize:15.0]}
                                                                                            forState:UIControlStateNormal];
}

 

我已經寫好的導航欄樣式庫:https://github.com/Jonear/JNNavigation (歡迎你們使用)

相關文章
相關標籤/搜索