全部產品
Search
文件中心

Mobile Platform as a Service:iOS 定製導覽列

更新時間:Jul 13, 2024

在 App 開發的過程中,經常會要求對頂部導覽列進行自訂。本文將介紹在基於 mPaaS 架構建立的頁面中,自訂導覽列的方法。包括定製應用主題和定製某一個頁面導覽列樣式。

基礎概念

導覽列元素分布

導覽列元素主要分布在三個地區。一般對導覽列的定製化需求,最終都會變為對這幾個地區的修改:

edit.png

  1. back:返回按鈕控制地區,由 mPaaS 頁面基類建立,預設樣式為返回箭頭 + 返迴文案。

  2. title/subTitle:標題列控制地區,預設不顯示。若需顯示,請調用系統方法設定當前頁面的 title。

  3. optionMenu:頁面菜單選項地區,預設不顯示。如需顯示,請調用系統方法設定當前頁面的 rightNavigationItem。

導覽列結構

  • 如下圖所示,基於 mPaaS 架構建立的應用,預設的 UI 結構為:window/navigationController > tabViewController > 每個 tab 嵌入一個 viewController。即應用主 window 的根應用是一個 UINavigationController 的對象,UINavigationController 的根應用是一個 UITabViewController導覽列結構

  • 由以上 UI 結構可以看出,整個應用全域只有一個 navigationController,因此所有頁面共用同一個導覽列(預設使用 APNavigationBar 建立)。

    導覽列結構-UI.png

  • 為了統一所有頁面的導覽列樣式,要求 mPaaS 應用中,所有頁面所在的 VC 都要繼承 DTViewControler,包括 native 和 H5 頁面。

  • 基於 mPaaS 架構建立的應用的預設主題,主白底黑字藍按鈕:

    ddd

定製應用主題

每個應用都會有自己的主題風格,根據以下描述修改 mPaaS 應用的預設主題:

  • 修改導覽列背景色、返回控制地區、標題控制地區等,可重寫 AUThemeManager 類的 au_defaultTheme_extraInfo 方法,修改以下 key 對應的傳回值。

    • 介面方法

      @interface AUThemeManager(AUExtendinfo)
      /*支付寶用戶端存在預設主題,獨立 App 可修改該預設值
      * 在該方法中只需返回與預設主題不同的索引值對即可,請使用 AUTheme.h 中定義好的 key
      */
      +(NSDictionary *)au_defaultTheme_extraInfo;
      
      @end
      /*
      *  例如
      *  +(NSDictionary*)au_defaultTheme_add_Info
      *  {
      *    NSMutableDictionary *dict = [INSMutableDictionary alloc] init];
      *    dictITITLEBAR_BACKGROUND_COLOR] = AU_COLOR_APP_GREEN; // AUTitleBar 背景色
      *    dit[TITLEBAR TITLE TEXTCOLOR1 = [UIColor redColor];   // AUTitleBar 標題色
      *    ...
      *    return dict;
      *  }
      */
    • 程式碼範例

      @implementation AUThemeManager (Portal)
      
      + (NSDictionary *)au_defaultTheme_extraInfo
      {
          NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
          dict[TITLEBAR_BACKGROUND_COLOR] = @"COLOR(#108EE9,1)"; // 導覽列背景色
          dict[TITLEBAR_LINE_COLOR] = @"COLOR(#108EE9,1)";       // 導覽列底部分割線或邊線的顏色
          dict[TITLEBAR_TITLE_TEXTCOLOR] = @"COLOR(#ffffff,1)";  // 導覽列標題色
          dict[TITLEBAR_TITLE_TEXTSIZE_BOLD] = @"FONT(18)";      // 導覽列標題大小
          dict[TITLEBAR_TEXTCOLOR] = @"COLOR(#ffffff,1)";        // 導覽列返回按鈕顏色
      
          return dict;
      }
      
      @end
      }
      說明

      顏色值必須使用類如 COLOR(#108EE9,1) 的方式,否則會報錯。

  • 修改主題配置中返回按鈕圖片,需重寫 AUBarButtonItem 類中的 au_default_backButtonImg 方法。

    • 介面方法

      #import "AUUILoadDefine.h"//程式自動產生
      #ifdef ANTUI_UI_TitleBar_AUBarButtonltem//程式自動產生
      //
      // AUBarButtonltem+AUExtendInfo.h
      // AntUI
      //
      // Copyright © 2017 Alipay. All rights reserved.
      //
      #import "AUBarButtonltem.h"
      
      @interface AUBarButtonltem(AUExtendInfo)
      
      //支付寶返回按鈕預設是藍色 icon,獨立 App 可修改返回按鈕預設表徵圖
      +(UIImage *)au_default_backButtonlmg;
      
      @end
    • 程式碼範例

      @implementation AUBarButtonItem (CGBBarButtonItem)
      
      + (UIImage *)au_default_backButtonImg
      {
          // 自訂返回按鈕的圖片
          return  APCommonUILoadImage(@"back_button_normal_white");
      
      }
      @end
  • 修改所有頁面的返回按鈕樣式和文案。

定製某一個頁面導覽列樣式

除了定製主題外,有時也需定製當前頁面的導覽列的樣式,如修改背景顏色、返回按鈕樣式等,根據修改時機不同,mPaaS 提供了不同的方法。

  • 頁面載入前,在預設導覽列樣式基礎上修改導覽列顏色,可以在當前頁面所在的 VC 中,實現 DTNavigationBarAppearanceProtocol 中的定義方法,來修改對應地區的顏色。

    • 介面方法

      @protocol DTNavigationBarAppearanceProtocol<NSObject>
      
      @optional
      
      /** 這個 DTViewController 是否要自動隱藏navigationBar,預設為 NO。業務某個 ViewController 需要隱藏 NavigationBar 可以重載此方法並返回 YES.
      **/
      -(BOOL)autohideNavigationBar;
      
      /** 當前 VC 隱藏導覽列後,如果需要設定一個全透明的導覽列,且當前頁面需設定與架構邏輯一致的返迴文案,請重載此方法,並返回一個 APCustomNavigationView 的執行個體
      -(UIView *)customNavigationBar;
      
      /** 如果某個 viewcontroller 希望自己的 titlebar 是不透明,並且指定一個顏色,可以重寫這個方法,並返回希望的顏色。
      * 僅限於被 Push 的 VC,tabbar 裡的 VC 還是不允許修改 navigationBar 的半透明屬性
      */
      -(UIColor *)opaqueNavigationBarColor;
      
      /**
       *  如果某個viewcontroller希望修改狀態列的樣式,請重寫此方法,並返回希望的style
       */
      - (UIStatusBarStyle)customStatusBarStytle;
      
      /**
       *  如果某個viewcontroller希望修改導覽列標題的顏色,請重寫此方法,並返回希望的顏色
       */
      - (UIColor *)customNavigationBarTitleColor;
    • 程式碼範例

      #pragma mark DTNavigationBarAppearanceProtocol:進入頁面時修改導覽列樣式
      - (UIColor *)opaqueNavigationBarColor
      {
          // 設定當前頁面導覽列背景為紅色
          return [UIColor redColor];
      
      //    // 設定當前頁面導覽列透明
      //    return [UIColor colorWithRGB:0xff0000 alpha:0];
      }
      
      - (BOOL)autohideNavigationBar
      {
          // 設定當前頁面導覽列是否隱藏
          return NO;
      }
      
      - (UIStatusBarStyle)customStatusBarStytle
      {
          // 設定當前頁面狀態列樣式
          return UIStatusBarStyleDefault;
      }
      
      - (UIColor *)customNavigationBarBackButtonTitleColor
      {
          // 設定當前頁面返回按鈕文案顏色
          return [UIColor greenColor];
      }
      
      - (UIImage *)customNavigationBarBackButtonImage
      {
          // 設定當前頁面返回按鈕圖片
          return APCommonUILoadImage(@"back_button_normal_white");
      }
      
      - (UIColor *)customNavigationBarTitleColor
      {
          // 設定當前頁面標題顏色
          return [UIColor greenColor];
      }
  • 頁面開啟後,在使用者操作的過程中動態修改導覽列樣式,如背景顏色滑動漸層、修改右側功能表按鈕等,根據修改的地區不同,主要分為以下幾類:

    • 背景地區:包括隱藏/顯示導覽列、透明導覽列、修改導覽列背景顏色、修改狀態列顏色。

      - (void)gotoHideNavigator
      {
          // 隱藏導覽列
          [self.navigationController.navigationBar setHidden:YES];
      }
      
      - (void)gotoShowNavigator
      {
          // 顯示導覽列
          [self.navigationController.navigationBar setHidden:NO];
      }
      
      - (void)gotoTransparency
      {
          // 透明導覽列
          [self.navigationController.navigationBar setNavigationBarTranslucentStyle];
      }
      
      - (void)gotoUpdateBackgroundColor
      {
          // 修改導覽列背景顏色
          [self.navigationController.navigationBar setNavigationBarStyleWithColor:[UIColor whiteColor] translucent:NO];
          [self.navigationController.navigationBar setNavigationBarBottomLineColor:[UIColor whiteColor]];
      }
      
      - (void)gotoUpdateStatusBarStyle
      {
          // 修改狀態列顏色
          [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
      }
    • 返回控制地區:修改預設返回按鈕文案顏色、修改預設返回按鈕返回箭頭樣式、重新設定返回按鈕樣式。

      - (void)gotoUpdateBackTitleColor
      {
          // 修改預設返回按鈕文案顏色
          NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
          if ([leftBarButtonItems count] == 1) {
              if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
                  AUBarButtonItem *backItem = leftBarButtonItems[0];
                  backItem.titleColor = [UIColor blackColor];
              }
          }
      }
      
      - (void)gotoUpdateBackImage
      {
          // 修改預設返回按鈕返回箭頭樣式
          NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
          if ([leftBarButtonItems count] == 1) {
              if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
                  AUBarButtonItem *backItem = leftBarButtonItems[0];
                  backItem.backButtonImage = APCommonUILoadImage(@"back_button_normal");
              }
          }
      }
      
      - (void)gotoUpdateBackItem
      {
          // 重新設定返回按鈕樣式
          self.navigationItem.leftBarButtonItem = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeDelete target:self action:@selector(onClickBack)];
      }
      
      - (void)onClickBack
      {
          [self.navigationController popViewControllerAnimated:YES];
      }
    • 標題控制地區:修改預設標題顏色、設定上下主副標題、修改標題為圖片顯示。

      - (void)gotoUpdateTitleColor
      {
          // 修改標題顏色
          [self.navigationController.navigationBar setNavigationBarTitleTextAttributesWithTextColor:[UIColor blackColor]];
      }
      
      - (void)gotoTwoTitle
      {
          // 修改標題樣式:上下主副標題
          self.navigationItem.titleView = [[AUDoubleTitleView alloc] initWithTitle:@"主標題" detailTitle:@"副標題"];
      }
      
      - (void)gotoTitleImage
      {
          // 修改標題樣式:圖片
          UIImageView *imageView = [[UIImageView alloc] initWithImage:APCommonUILoadImage(@"ilustration_ap_expection_alert")];
          imageView.frame = CGRectMake(0, 0, self.self.view.width-100, 64);
          self.navigationItem.titleView = imageView;
      }
    • 菜單控制地區:設定單個或多個右側功能表按鈕。

      - (void)gotoSetOptionMenu
      {
          // 設定右側單按鈕
          self.navigationItem.rightBarButtonItem = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeGroupChat target:self action:@selector(onClickRightItem)];
      }
      
      - (void)gotoSetTwoOptionMenu
      {
          // 設定右側雙按鈕
          AUBarButtonItem *item1 = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeGroupChat target:self action:@selector(onClickRightItem)];
          AUBarButtonItem *item2 = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeHelp target:self action:@selector(onClickRightItem)];
          self.navigationItem.rightBarButtonItems = @[item1, item2];
      }
  • 沈浸式導覽列:進入時導覽列透明,滑動到指定位置後不透明。主要分為以下兩類:

    • 進入頁面時,設定導覽列透明:在當前頁面所在的 VC 中重寫以下介面。

      - (UIColor *)opaqueNavigationBarColor
        {
            // 設定當前頁面導覽列透明
            return [UIColor colorWithRGB:0xff0000 alpha:0];
        }
    • 頁面滑動到指定位置後,修改導覽列背景地區、返回地區、標題區及菜單控制地區等樣式。

        - (void)gotoUpdateBackgroundColor
        {
            // 修改導覽列背景顏色
            [self.navigationController.navigationBar setNavigationBarStyleWithColor:[UIColor whiteColor] translucent:NO];
            [self.navigationController.navigationBar setNavigationBarBottomLineColor:[UIColor whiteColor]];
        }
      
        - (void)gotoUpdateBackTitleColor
        {
            // 修改預設返回按鈕文案顏色
            NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
            if ([leftBarButtonItems count] == 1) {
                if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
                    AUBarButtonItem *backItem = leftBarButtonItems[0];
                    backItem.titleColor = [UIColor blackColor];
                }
            }
        }
      
        - (void)gotoUpdateTitleColor
        {
            // 修改標題顏色
            [self.navigationController.navigationBar setNavigationBarTitleTextAttributesWithTextColor:[UIColor blackColor]];
        }