iOS- 一種自定義NavigationBar的方式

NavigationBar這個最基本的控件想必大家都接觸的不少,更是有各種各樣的自定義的方式。我這邊也分享一種根據(jù)項目需求而構(gòu)想的自定義NavigationBar,可能并不是很通用,權(quán)當參考。

先看下項目界面簡圖:

界面.png

Bar左邊三個控件,返回按鈕,logo圖片,當前頁面的title相對來說是固定的,除了最基礎(chǔ)的幾個Tab頁面不需要返回按鈕,每個頁面都有這三個控件。
Bar右邊是不同的功能按鈕,數(shù)量0-3個不等。

接下來具體實現(xiàn)。
采用UIView來模擬NavigationBar,所以在NavigationController中先隱藏navigaitonBar

self.navigationBar.hidden = YES;

然后將自定義的navigationBar(下稱CustomNaviBar)添加到NavigationController中。

CustomNaviBar初始創(chuàng)建時只添加logo imageView和title Label這兩個控件。

CustomNaviBar提供如下幾個方法:

/**
更新當前頁面title
頁面初始化時調(diào)用 (建議viewDidAppear)
*/
- (void)updateNaviBarTitle:(NSSring *)title;

更新title方法實現(xiàn)即給Label賦值,設(shè)置布局,這里提一個小點,為了某些頁面title是靈活配置的布局正常,傳入的title去除收尾空格。

self.titleLabel.text = [title stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

/**
 添加返回按鈕
 push到下一個頁面時,在NavigationController中調(diào)用
*/
- (void)remakeSubViewsForBackBtn;

這個方法顧名思義,添加返回按鈕。方法的實現(xiàn)也僅僅是添加按鈕,調(diào)整控件布局。
在調(diào)用時,可以在NavigationController中調(diào)用

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    [super pushViewController:viewController animated:YES];
    [self.baseNaviBar remakeSubViewsForBackBtn];
}
/**
 清除返回按鈕
 */
- (void)clearForBackBtn;

有創(chuàng)建也就有移除,返回到基礎(chǔ)Tab頁面時需要調(diào)用此方法來清除返回按鈕。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.naviController.baseNaviBar updateNaviBarTitle:@"主頁"];
    [self.naviController.baseNaviBar clearForBackBtn];
}
/**
單獨添加一個右邊的按鈕
*/
- (void)addSingleRightBtnWithTitle:(NSString *)title ButtonImage:(NSString *)imageName Target:(id)target Action:(SEL)action;

剛剛提到右側(cè)的功能鍵數(shù)量0-3個不等,這里先給到一個創(chuàng)建一個按鈕的方法,方法參數(shù)中傳入target以及點擊事件。
此方法的實現(xiàn)中,除了給btn布局和添加點擊事件以外,需要提一小點是

[self.rightButton setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];

設(shè)置約束的優(yōu)先級,以免某些頁面title文字過長導(dǎo)致和右側(cè)按鈕約束沖突。

/**
 添加自定義按鈕
 由右向左添加!
 填入buttonTitles參數(shù)也按照從右向左的順序。
 buttonConfiguration:
 @{
 @"title":@"標題",
 @"image":@"圖片名",
 @"action":action,//button點擊方法,傳入NSInvocation類型參數(shù)
 }
 */
- (void)addButtonWithButtonConfiguration:(NSDictionary *)buttonConfiguration,...NS_REQUIRES_NIL_TERMINATION;

右側(cè)有多個按鈕的頁面就由此方法來實現(xiàn),比較關(guān)鍵的兩點是:
1> NS_REQUIRES_NIL_TERMINATION 宏
在創(chuàng)建字典,數(shù)組時肯定沒少用過這類方法

NSArray arrayWithObjects:<#(nonnull ObjectType), ...#>, nil

自己來實現(xiàn)這個寫法時,核心代碼如下:

- (void)addButtonWithButtonConfiguration:(NSDictionary *)buttonConfiguration, ... {
    va_list argList;
    if (buttonConfiguration) {
        va_start(argList, buttonConfiguration);
        NSDictionary *configuraDict;
        //這樣每次循環(huán)argList所代表的指針偏移量就不斷下移直到取出nil
        while ((configuraDict = va_arg(argList, id))) {
             //這里設(shè)置btn布局,添加點擊事件
        }
    }
    va_end(argList);
}

2>傳入NSInvocation類型參數(shù)
直接上代碼,創(chuàng)建一個NSInvocation對象

+ (NSInvocation *)creatInvocationWithTarget:(id)target Action:(SEL)action {
    NSMethodSignature *signature = [target methodSignatureForSelector:action];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = target;
    invocation.selector = action;
    return invocation;
}

NSInvocation有其他更有趣好用的使用場景,在此處大材小用了,僅僅是因為需要作為參數(shù)包裝到字典中,其他用法這里先不贅述了。

添加btn方法調(diào)用示例如下:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.naviController.baseNaviBar updateNaviBarTitle:@"主頁"];
    [self.naviController.baseNaviBar clearForBackBtn];

    [self.naviController.baseNaviBar addButtonWithButtonConfiguration:
     @{@"title":@"btn1",@"image":@"image1",@"action":[CreatActionTool creatInvocationWithTarget:self Action:@selector(click1)]},
     @{@"title":@"btn2",@"image":@"image2",@"action":[CreatActionTool creatInvocationWithTarget:self Action:@selector(click2)]},nil];
}

在添加btn點擊事件時如下:

 NSInvocation *action = [configuraDict objectForKey:@"action"];//configuraDict為在上述方法中循環(huán)取出的btn配置數(shù)據(jù)
 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
 [button addTarget:action.target action:action.selector forControlEvents:UIControlEventTouchUpInside];


提供主要功能的幾個方法如上所述,還可以隨意添加一些自定義功能。
因為代碼中為了項目需求,做了好多適配,也不是通用的方法,后面整理好再上傳~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 程孤帆不解其意,走過去才見里面數(shù)層放著一卷卷東西。 他隨手揀起一卷,見封皮上寫著“千秋山莊”。數(shù)十年前,千秋山莊全...
    德萬托阿閱讀 676評論 0 5
  • 【周檢視】2017年8月14日-8月20日 好好讀書,好好健身,好好愛自己 一 健康 這一周每天都有堅持5.30打...
    huiyoulanda閱讀 239評論 0 0

友情鏈接更多精彩內(nèi)容