App開發流程之狀態欄和導航欄

来源:http://www.cnblogs.com/ALongWay/archive/2016/09/21/5891952.html
-Advertisement-
Play Games

記錄狀態欄和導航欄的設置和控制,統一在基類視圖控制器中完成。 狀態欄。 狀態欄高度為20,iOS7以後背景完全透明。 樣式枚舉如下: typedef NS_ENUM(NSInteger, UIStatusBarStyle) { UIStatusBarStyleDefault = 0, // Dark ...


記錄狀態欄和導航欄的設置和控制,統一在基類視圖控制器中完成。

狀態欄。

狀態欄高度為20,iOS7以後背景完全透明。

樣式枚舉如下:

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {

    UIStatusBarStyleDefault                                     = 0, // Dark content, for use on light backgrounds

    UIStatusBarStyleLightContent     NS_ENUM_AVAILABLE_IOS(7_0) = 1, // Light content, for use on dark backgrounds    

    UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,

    UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,

} ;

動畫枚舉如下:

typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {

    UIStatusBarAnimationNone,

    UIStatusBarAnimationFade,

    UIStatusBarAnimationSlide,

} ;

 

舊的常用設置方式:

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

但是iOS9以後廢棄了這些方法。就算是在iOS7上,如果啟用了基於UIViewController的狀態欄控制系統,上述方法也將失效。

UIApplication.h中的註釋內容為:Setting the statusBarStyle/statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.

iOS7以後預設開啟了UIViewController的狀態欄控制系統。如果需要關閉,並採用舊的設置方式,可以將Info.plist中鍵值View controller-based status bar appearance設置為NO。

 

新的設置方式:

- (UIStatusBarStyle)preferredStatusBarStyle; // Defaults to UIStatusBarStyleDefault

- (BOOL)prefersStatusBarHidden; // Defaults to NO

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation; // Defaults to UIStatusBarAnimationFade

// This should be called whenever the return values for the view controller's status bar attributes have changed. If it is called from within an animation block, the changes will be animated along with the rest of the animation block.

- (void)setNeedsStatusBarAppearanceUpdate;

上述方法,均為UIViewController的實例方法,前三個方法可以在子類中被重寫,最後主動調用setNeedsStatusBarAppearanceUpdate才會生效。

 

為了便於切換控制方式,提供巨集控制方案:

1.在Info.plist文件中增加鍵值View controller-based status bar appearance = NO

2.在基類控制器的頭文件中定義如下巨集,便於子類檢查是否啟用該巨集定義

//使用基於視圖控制器的狀態欄控制系統,UIApplicationsetStatusBarHidden類似方法將無效

//開啟此巨集定義,請將Info.plistView controller-based status bar appearance設置為YES,否則置為NO

#define UseDefaultUIViewControllerBasedStatusBarSystem

3.提供相關屬性以設置狀態欄,提供相關方法更新狀態欄,併在實現文件中增加條件判斷巨集

#ifdef UseDefaultUIViewControllerBasedStatusBarSystem

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return self.statusBarStyle;
}

- (BOOL)prefersStatusBarHidden
{
    return self.willHideStatusBar;
}

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationFade;
}

#endif

- (void)updateStatusBar
{
#ifdef UseDefaultUIViewControllerBasedStatusBarSystem
    [self setNeedsStatusBarAppearanceUpdate];
#else
    [[UIApplication sharedApplication] setStatusBarHidden:self.willHideStatusBar withAnimation:UIStatusBarAnimationFade];
    [[UIApplication sharedApplication] setStatusBarStyle:self.statusBarStyle];
#endif
}

 

導航欄

導航欄高44,iOS7以後預設透明,由UINavigationBar的translucent屬性決定

1.設置導航欄顯示屬性,更多是在設置UINavigationController的UINavigationBar屬性。UIViewController中也存在UINavigationController類型的屬性,參考如下:

[self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
[self.navigationController.navigationBar setTranslucent:YES];
[self.navigationController.navigationBar setBackgroundImage:[ImageHelper getImageWithColor:NaviBarColor] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[ImageHelper getImageWithColor:NaviBarShadowColor]];
[self.navigationController.navigationBar setTitleTextAttributes:NaviBarTitleAttributes];

 

2.設置標題、按鈕相關屬性,關註UIViewController的UINavigationItem屬性

3.隱藏導航欄,可以設置navigationBarHidden屬性,但建議使用方法

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated; // Hide or show the navigation bar. If animated, it will transition vertically using UINavigationControllerHideShowBarDuration.

如果上一個界面顯示導航欄,下一個界面隱藏導航欄(帶有返回上一個界面的功能方法),界面切換可能出現導航欄過渡效果不佳的情況。在viewWillAppear方法中,使用代碼

[self.navigationController setNavigationBarHidden:self.willHideNavigationBar animated:animated];

可以得到較好的切換效果。

4.如果帶有bottomBar,當新的UIViewController將要被push到導航棧top前,可以使用UIViewController的hidesBottomBarWhenPushed控制bottomBar顯示

5.合理使用導航欄控制的屬性viewControllers和方法:

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated NS_AVAILABLE_IOS(3_0); // If animated is YES, then simulate a push or pop depending on whether the new top view controller was previously in the stack.

可以實現導航棧中的視圖控制器切換、替換、新增、移除等功能效果。

6.導航控制的如下代理方法,可以實現切換動畫的自定義,後續記錄一個實現返回手勢控制的分類將涉及到

- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController

                          interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0); 

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController

                                   animationControllerForOperation:(UINavigationControllerOperation)operation

                                                fromViewController:(UIViewController *)fromVC

                                                  toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);

 

UIViewController的self.view佈局問題

單獨一個視圖控制器的self.view應該是充滿容器的,origin為(0, 0),增加導航欄以後,如果不設置,仍然為(0, 0),將增加subview佈局的麻煩。所以,需要關註如下屬性:

@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll

@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.  

extendedLayoutIncludesOpaqueBars屬性,該屬性表示是否包括不透明bars,預設不包括,但是iOS7以後,狀態欄和導航欄都是預設透明的,所以self.view預設與屏幕邊緣貼合。

edgesForExtendedLayout決定了self.view與邊緣的距離,預設貼合邊框,當增加導航欄以後,需要設置為UIRectEdgeNone,使self.view上邊緣與導航欄下邊緣貼合。

 

下圖為self.edgesForExtendedLayout = UIRectEdgeNone;

說明:導航欄下的紅條origin為(0, 0)且高20,黑條高44,藍條高44。

 

下圖為self.edgesForExtendedLayout = UIRectEdgeAll;

 

 

無導航欄時候,兩種設置,紅條都靠著頂部。

 

UIViewController的automaticallyAdjustsScrollViewInsets屬性。

該屬性自動設置self.view上scrollView類型的subview的insets,預設為YES。

當導航欄隱藏時候,該屬性會導致scrollView的contentView的offsetY自動為20,也就是看到scrollView內容從狀態欄下邊緣開始顯示,這也將帶來很多麻煩。

所以導航欄隱藏時候設置self.automaticallyAdjustsScrollViewInsets = !willHideNavigationBar;可以避免意外的顯示異常。 

 

下一篇記錄一個實現返回手勢的分類。

 

base項目已更新:[email protected]:ALongWay/base.git


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 幀動畫——FrameAnimation 將一系列圖片有序播放,形成動畫的效果。其本質是一個Drawable,是一系列圖片的集合,本身可以當做一個圖片一樣使用 在Drawable文件夾下,創建animation-list為根節點的資源文件 <animation-list android:oneshot ...
  • PhotoKit 是ios9以後取代 ALAssetLibrary 的一種新框架,註意是框架不是頭文件,不是可掉出來的系統名只是一個框架名,代表一個框架種類。所以你在xcode中你輸photoKit什麼也沒有,當你輸了n遍試了n遍之後你會發現什麼有沒有。納里什麼鬼,呵呵你被坑了吧。那麼大家就要問了怎 ...
  • 在程式開發中,數據層永遠是程式的核心結構之一。我們將現實事物進行抽象,使之變成一個個數據。對這些數據的加工處理是代碼中能體現技術水平的一大模塊,比如數據的請求、解析、緩存、持久化等等。適當的對數據進行持久化存儲可以實現應用的離線功能,以此提高用戶體驗。在iOS開發中,蘋果提供了四種持久化方案供我們選 ...
  • iOS7以後,導航控制器,自帶了從屏幕左邊緣右滑返回的手勢功能。 但是,如果自定義了導航欄返回按鈕,這項功能就失效了,需要自行實現。又如果需要修改手勢觸發範圍,還是需要自行實現。 廣泛應用的一種實現方案是,採用私有變數和Api,完成手勢交互和返回功能,自定義手勢觸發條件和額外功能。 另一種實現方案是 ...
  • 生命周期:因為Presenter是View創建的,我們需要確保完全地理解View的生命周期,特別是因為它將最有可能去處理狀態更新和非同步數據。舉個例子,每一個Presenter應該在View destroyed的情況下有一個取消非同步任務的方式,或者應該在用戶暫停或者恢復視圖事件時重置到原始狀態等等。最 ...
  • 前言: 關於.jar文件: 平時我們Android項目開發中經常會用到第三方的.jar文件。 其實.jar文件就是一個類似.zip文件的壓縮包,裡面包含了一些源代碼,註意的是.jar不包含資源文件(res、圖片等) 一、首先學習如何在Android studio中將android項目打成.jar文件 ...
  • FMDB的使用 一:瞭解FMDB的三個重要類 1.1 FMDataBase:提供SQLite資料庫的類,用來執行SQL語句 1.2 FMResultSet: 用在FMDatabase中執行查詢結果的類 1.3 FMDatabaseQueue:在多線程下查詢和更新資料庫用到的類 二:使用FMDB 2. ...
  • android主要三大佈局:線性佈局LinearLayout、相對佈局RelativeLayout、幀佈局FrameLayout。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...