- 首先是導航控制器下的視圖結構
導航控制器的三個區:
導航區:導航控制器的navigationBar,管NSArray<UINavigationItem *> *items;數組
內容區:用于展示導航控制器字控制器的視圖
toolbar區:底部工具條,默認隱藏-
導航條的隱藏和展示:
通過navigationBar.translucent = YES/NO調節。
透明情況下:
內容區從屏幕頂部開始, 控制器view的frame為 0 0 screenW screenH(控制器的View的frame相對于UIViewControllerWrapperView計算)
透明情況下,讓控制器的展示區從導航條底部開始:self.edgesForExtendedLayout = UIRectEdgeNone;設置后,展示區的高度同樣-64px。同時automaticallyAdjustsScrollViewInsets失效,scrollView的bounds不自動下移。
測試:UIViewControllerWrapperView = self.view.superView。更改bounds也可以讓self.view下移64,
導航條不透明情況下:
展示區從導航條下開始 。
導航條不透明情況讓展示區頂部從屏幕頂部開始:self.extendedLayoutIncludesOpaqueBars = YES; 同時automaticallyAdjustsScrollViewInsets生效。同時automaticallyAdjustsScrollViewInsets自動生效,scrollView的bounds自動下移。無論導航條是否透明,UILayoutContainerView、UINavigationTransitionView、UIViewControllerWrapperView都是和屏幕尺寸一致的,變化的只是展示區域的frame,即子控制器的view的frame。
測試:導航控制器下view加載:只要在控制器view不是從頂部0開始的情況下,控制器的view的y和height都是不準確的,當子控制器的viewDidAppear的時候,它的frame是會被重新定義成展示區的尺寸。我把展示區理解成子控制器viewDidAppear后的frame。 導航條透明度的調節:
方法一:通過setBackgroundImage調節。
viewDidLoad、viewWillAppear設置setBackgroundImage為一張透明度為1.0的圖片話,相當于設置navigationBar.translucent = NO,展示區下移64px,高度減少64px。
viewDidAppear設置setBackgroundImage為一張透明度為1.0的圖片話,相當于設置navigationBar.translucent = NO。但是當前控制器不會顯現,展示區還是0px,高度還是屏幕的尺寸,內部的scrollView的bounds還是會自動加64px。pop回上一層控制器后,展示區下移64px,高度減少64px。如果設置setBackgroundImage為一張透明度小于1.0的圖片話,就不會出現navigationBar.translucent狀態不會修改。
解決的設置非透明圖片后,頂欄透明自動關閉的問題:
viewDidLoad設置
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:JKRColor(255, 255, 0, 1.0)] forBarMetrics:UIBarMetricsDefault];
self.extendedLayoutIncludesOpaqueBars = YES;
viewWillDisappear設置
self.navigationController.navigationBar.translucent = YES;
解決設置完setBackgroundImage為一張非透明圖片之后,展示區頂部回到0位置:再設置self.navigationController.navigationBar.translucent = YES;會回恢復展示區y為0的位置,但是設置的圖片會自動加一些透明度。
會出現的問題:如果設置setBackgroundImage同時設置barTinkColor,那么圖片透明會漏出_UIBarBackground的顏色。
如果設置上一級的控制器設置了setBackgroundImage,下一級的控制器設置setBackgroundImage圖片為透明色后,底部_UIBarBackground的變為不透明,漏出黑色,不能穿透顯示底部視圖。
方法二:通過修改_UIBarBackground的背景色
首先viewDidLoad中定義當前控制器的導航條為非透明狀態,展示區不自動下移。
設置導航條背景色被透明。
遍歷導航條獲取到_UIBarBackground
根據透明度設置其顏色
pop時,即viewWillDisappear時重新定義導航條為透明
遇到的問題:當側滑并返回不POP的時候,當前控制器的導航條的_UIBarBackground背景色雖然透明,但是導航條還是白色,觀察發現,因為POP一半的時候走了viewWillDisappear并執行self.navigationController.navigationBar.translucent = YES;返回的時候,導致導航條內部增加了UIVisualEffectView。我嘗試在viewDidAppear中遍歷出這個視圖移除,但是沒有效果。發現控制器的view加載成功后,再次對導航條修改必須要等viewDidAppear后一段時間才可以,沒有找出來原因。代碼如下:
5.導航條下劃線的隱藏:
方法一:設置navigationBar的clipsToBounds。問題:navigationBar為44高度,有背景色的時候會發現問題。
方法二:遍歷出下劃線的UIImageView并隱藏。原理:因為下劃線的高度為0.333,以高度不大于0.4為條件便利導航條的子視圖。
6.Item間距問題。
UIBarButtonItem *itemGap = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
itemGap.width = 80;
把間距的item添加到items對象數組中要添加間距的兩個對象之間即可