在開發過程中,如果你用的是傳統的樣式頂部20px的statusbar加上下面44高度的
navigationBar的話, 這樣的產品經理真的是太好了,很簡單,但是現在越來越多的人自
定義導覽列,看起來就沒有系統那麼呆板,但是我就是不想自訂,我想自己更改系統導
航欄的各種屬性和frame。
首先,看看自己需要什麼樣子的
1.導覽列底部的1px像素我要去掉,需要一個純淨的
2.導覽列的高度我要更改為例如100
3.導覽列高度變化的時候,裡面的leftBarItem和rightBarItem以及titleView也要跟著垂直置中
下面請看圖
有瑕疵啊有瑕疵,底部的1px還在
再來一張 這個就沒有瑕疵了
非常完美乾淨,有潔癖的看起來真的很舒服好麼。。。
上面列出了三個需要解決的問題,咱們來一個個解決,我這裡用了遞迴,還不錯哦
第一個問題:導覽列底部1px是什麼,怎麼讓他不顯示
先來看一張圖,他到底是什麼東東,我用的是Reveal開啟的,你也可以用Xcode內建的
開啟如下,這是圖形介面
以下是樹形圖,對應的那個控制項UIImageView
沒錯,就是他,UIImageView,Frame為0.5的那個,直接擼代碼遞迴它
UIImageView *cancelImageView = [self searchNavigationBarUnderLine:self.navigationController.navigationBar]; cancelImageView.hidden = YES;
- (UIImageView *)searchNavigationBarUnderLine:(UIView *)view{ // 尋找是否屬於UIImageView以及Frame是否小於1.0 if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height < 1.0f) { return (UIImageView *)view; } // 迴圈第二層尋找 for (UIView *subView in view.subviews) { // 遞迴尋找 UIImageView *imageView = [self searchNavigationBarUnderLine:subView]; if (imageView) { return imageView; } } return nil;}
這行代碼遞迴尋找出是否有個控制項UIImageView而且他的frame的高度是小於1.0的,這樣就能把多餘的1pxHidden了
是不是很乾淨了,OK,那麼第一個問題解決了
第二個問題:如何更改導覽列的高度(這個東西有點棘手,去github找找資源)
JZNavigationExtension,就是他,幫你們找到現成的了,他能更改導覽列很多屬性,咱們先用一個更改frame
傳送門:點擊開啟連結
platform:ios,'7.0'
target '遞迴的方法取消1px' do
pod 'JZNavigationExtension'
end
之後你只要包括他的標頭檔
#import "JZNavigationExtension.h"
[self.navigationController setJz_navigationBarSize:CGSizeMake([UIScreen mainScreen].bounds.size.width, 100)];
搞定啦,同學
第三個問題:如何讓導覽列上的控制項垂直置中
天真的我以為,第二個問題解決之後呢,你往上面放UIBarButtonItem和NavigationItem的title是預設垂直置中的
然而現實是殘酷的,內部layoutSubviews根本不知道在幹嘛,為嘛不置中嘞。。。
現在的思路大概是,要在重新LayoutSubviews的時候重新進行置中,系統不置中,咱們自己寫一個Category,調用父
類的同時子類重新布局,從而達到所有控制項置中的效果
#import "UINavigationBar+CustomHeight.h"@implementation UINavigationBar (CustomHeight)- (CGSize)sizeThatFits:(CGSize)size { // Change navigation bar height. The height must be even, otherwise there will be a white line above the navigation bar. CGSize newSize = CGSizeMake(self.frame.size.width, 100); return newSize;}
-(void)layoutSubviews { [super layoutSubviews]; // Make items on navigation bar vertically centered. int i = 0; for (UIView *view in self.subviews) {// NSLog(@"<%i>. %@", i, [view description]); i++; // 這裡的1是背景imageView,不需要進行配置 if (i == 1) continue; // 這裡的3就是titleView,不設定就會有bug,title不會跟著置中,需要手動調節他子視圖Label的frame,這是個坑,一定要注意這樣寫 if (i == 3) { for (UILabel *label in view.subviews) { float y = (view.bounds.size.height - label.bounds.size.height) / 2; CGRect rec = label.frame; rec.origin.y = y; label.frame = rec; } } [self alignVerticalCenter:view]; } }- (void)alignVerticalCenter:(UIView *)view{ // 置中 float centerY = self.bounds.size.height / 2.0f; CGPoint center = view.center; center.y = centerY; view.center = center;}
這裡寫了一個方法自己查看UINavigationBar的所有視圖的遞迴,大家可以跟著查看列印日誌,這樣對內部的控制項布局
會更有理解
[self logView:self.navigationController.navigationBar]; }- (void)logView:(UIView *)view{ NSLog(@"<!>,%@",view.description); for (UIView *subView in view.subviews) { [self logView:subView]; }}
三個問題解決完了,這樣你就能讓你的導覽列隨心所欲的變化了,去掉了底部1px,而且高度也能隨時變化,內部控制項
也都置中了,反正我的問題解決了,各位有什麼新發現可以分享下
註:這裡分享個UIBarButtonItem的間距和位移問題
// 這個UIBarButtonSystemItemFixedSpace屬性沒有任何樣式,是專門給item之間加間隙的 正數間距越大,負數就越小 UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; spaceItem.width = 50; UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(clickRight)]; self.navigationItem.rightBarButtonItems = @[spaceItem,rightBarButton];
效果就是這樣的
基本上介紹到這裡就結束了,看到這裡的人,真心感謝你們,我認真寫,你們開心看,十分感謝
本次Demo傳送門:點擊傳送門下載Demo
Over~~~~~~