天天看點

iOS小技能:自定義導航欄控制器

I 自定義UITarBarController

為了減小iOS系統版本間的風格差異,經常采用自定義TarBar:

  1. 建立一個類,繼承自UITabBarController。
  2. 建立一個類,繼承自UIView,用來做TabBar,封裝内部的按鈕。
  3. 在自定義的UITabBarController中建立自定義的TabBar,添加到預設的UITabBar上面。

II 自定義導航欄控制器

iOS15 UI适配之導覽列主題: 背景顔色、标題顔色​​kunnan.blog.csdn.net/article/det…​​

2.1自定義導航控制器的價值

  1. 重寫push方法就可以攔截所有壓入棧中的子控制器,統一做一些處理。
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    [viewController setHidesBottomBarWhenPushed:YES];//隐藏BottomBar
    [super      
  1. 重寫pop方法就可以攔截所有子控制器的出棧
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;      

2.2 導航欄主題的設定

主要是取得導航欄的appearance對象,操作它就設定導航欄的主題

UINavigationBar *navBar = [UINavigationBar appearance];

設定導覽列主題

/*     @protocol UIAppearance <NSObject>  協定的代理方法+ (instancetype)appearance;

    @interface UIView : UIResponder < UIAppearance>
    */
   UINavigationBar *navigationBar =[UINavigationBar appearance];//擷取所有導覽列外觀
   [navigationBar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];      

導覽列的相容問題

//方式一:擷取全局外觀
//    UINavigationBar *navigationBar =[UINavigationBar appearance];//擷取所有導覽列外觀
    //方式二:擷取我們自己導航控制器的導覽列
    UINavigationBar *navigationBar;//確定系統的其它功能(短信)的導覽列與自己的沖突,尤其在短信分享這方面要注意
    if (IOS9) {
        //9.0的API
        navigationBar = [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[HLNavigationController class]]];
    }else{
        navigationBar = [UINavigationBar appearanceWhenContainedIn:[HLNavigationController class],nil];
    }      

常用主題設定

//*導航欄背景:
- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics;
//*标題:
  @property(nonatomic,copy) NSDictionary *titleTextAttributes;// 字典中能用到的key在UIStringDrawing.h中// 最新版本的key在UIKit架構的NSAttributedString.h中      

設定文字顔色

NSDictionary *dict = @{NSForegroundColorAttributeName:[UIColor whiteColor]};
[navigationBar setTitleTextAttributes:dict];
//2、The tint color to apply to the navigation items and bar button items. 導覽列的主題顔色
   [navigationBar setTintColor:[UIColor      

傳回按鈕的箭頭樣式​

​@property(nonatomic,retain) UIColor *tintColor;​

2.3 導航欄按鈕主題

UIBarButtonItem *item = [UIBarButtonItem appearance];
//設定主題的方法:
//背景:
- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics;
//文字:
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state;
//導航欄傳回按鈕背景:
- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics;      
+ (void) settingbarButtonItenAppearance{

    //2、The tint color to apply to the navigation items and bar button items. 導覽列的主題顔色

    //    [navigationBar setTintColor:[UIColor whiteColor]];

    /**

     NS_CLASS_AVAILABLE_IOS(2_0) @interface UIBarItem : NSObject <NSCoding, UIAppearance>

     */

    //導航欄按鈕主題

    UIBarButtonItem *barButtonIten = [UIBarButtonItem appearance];

    /*

     設定主題的方法:

     背景:- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics;

     文字:- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state;

     導航欄傳回按鈕背景:- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics;

     */

    [barButtonIten setTintColor:[UIColor whiteColor]];

    [barButtonIten setBackgroundImage:[UIImage imageNamed:@"NavButton"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    [barButtonIten setBackgroundImage:[UIImage imageNamed:@"NavButtonPressed"] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];

    [barButtonIten setBackButtonBackgroundImage:[UIImage imageNamed:@"NavBackButton"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    [barButtonIten setBackButtonBackgroundImage:[UIImage imageNamed:@"NavBackButtonPressed"] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];

}      

III 預備知識

  1. 在push控制器時隐藏UITabBar
viewController.hidesBottomBarWhenPushed = YES;      
  1. ninitailize、load方法的差別:
  • 當一個類被裝載進記憶體時,就會調用一次load方法(當時這個類還不可用)
  • 當第一次使用這個類時,就會調用一次initailize方法
  1. 狀态欄交給了UIApplication管理:
修改info.plist的viewController based status bar appearance 屬性
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>      
  1. 去除圖示的玻璃質感效果

取消蘋果自動添加高亮特效。

iOS小技能:自定義導航欄控制器
蘋果預設會在 App Store 裡的應用圖示上半部自動添加高亮特效,如果您要去掉這一高亮特效,可以在 info.plist 裡添加一個類型為 boolean 的字段:​

​UIPrerenderedIcon​

​,值設定為YES(或者是:Icon already includes gloss effects,值設定為YES)。

再上傳應用,App Store 就不會在圖示上添加高亮特效了

<key>UIPrerenderedIcon</key>
<true/>      
  1. UIImageView的圖檔拉伸
iOS小技能:自定義導航欄控制器

UIImaegView的圖檔拉伸可以通過storyboard或者xib設定

//  UIImage+ResizableImage.m//  20160525-QQinterface////  Created by devzkn on 3/26/16.//  Copyright © 2016 hisun. All rights reserved.//
#import "UIImage+ResizableImage.h"

@implementation UIImage (ResizableImage)

#pragma
/**
 建立“指定拉伸方式和拉伸小矩形”的圖檔
 */
+ (UIImage*)resizableImageWithName:(NSString *)name {
    UIImage *image = [UIImage imageNamed:name];
    //裁剪圖檔方式一:
    //Creates and returns a new image object with the specified cap values.
    /*right cap is calculated as width - leftCapWidth - 1
     bottom cap is calculated as height - topCapWidth - 1
     */
    return [image stretchableImageWithLeftCapWidth:image.size.width*0.5 topCapHeight:image.size.height*0.5];
    //方式二:
    //    CGFloat top = image.size.width*0.5f-1;
    //    CGFloat left = image.size.height*0.5f-1;
    //    UIEdgeInsets insets = UIEdgeInsetsMake(top, left, top, left);
    //    UIImage *capImage = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeTile];
    //      

see also