iOS 屏幕原點坐標 &&自定制導航欄的研究

一、屏幕原點坐標的研究

小伙伴們可能發現,我們給一個空間設置origin為(0,0)的時候,有時候這個點會再屏幕的最左上角(有導航欄的情況下還可能會被導航欄給蓋住),有時候又在導航欄的下邊,都是同樣的原點坐標,那么為什么會出現這種情況呢?下面給出答案:

一個controller的view的原點位置受self.navigationController. navigationBar 的 setTranslucent (BOOL) 屬性控制,在 iOS7 以后 translucent 屬性默認為 YES。

translucent 為YES:原點位置坐標為屏幕左頂端,即屏幕坐標系(0 , 0),含義為毛玻璃、半透明效果。

translucent 為NO:原點位置坐標為導航欄的下邊的左頂端,即屏幕坐標系(0 , 64),此時導航欄不透明。

注意,當我們設置navigationBar的背景圖片setBackgroundImage(注意是背景圖片不是背景顏色)的時候,坐標起點也會變成(0,64),因為當我們設置背景圖片的時候,系統會自動修改translucent為NO。

二、自定制導航欄

修改導航欄可以采用全局修改(一般在appDelegate中或者在父navigationController中設置navigationBar ),也可以單獨在相應的頁面設置。

全局appearance修改:

UINavigationBar * navigationBarApperance = [UINavigationBar appearance];

//后續對bar設置,代碼省略。

父navigationController修改:

獲取self.navigationBar設置,代碼省略。

單獨頁面設置:

self.navigationController.navigationBar設置,代碼省略。

注:下文我們的示例代碼都是全局設置。

1.修改導航欄的“背景”顏色

修改導航欄顏色有如下幾種方式:

1.1 通過backgroundColor進行設置:

UINavigationBar * navigationBarApperance = [UINavigationBar appearance];

navigationBarApperance.backgroundColor = [UIColor redColor];

navigationBarApperance.translucent = YES;

此方式需要translucent=YES為前提,而且設置出來的背景顏色不純,會被導航欄的毛玻璃效果遮擋(至于為什么會被遮擋下文會講),此方式基本不成功,效果太傻缺,而且效果產生的優先級會很低,如果后面再設置navigationBar的barTintColor,會覆蓋掉這個效果。

綜上,次方式直接廢棄。


backgroundColor.png

1.2 通過barTintColor進行設置:

UINavigationBar * navigationBarApperance = [UINavigationBar appearance];

navigationBarApperance.barTintColor = [UIColor redColor];


barTintColor.png

如上圖可以看到底部會有一條淺黃色(這個淺黃色是系統根據你導航欄的顏色自動適配的一個顏色)的分割線陰影,這條分割陰影是用來分割導航欄和下面視圖的。如你不想要分割線,你也可以通過設置相同顏色的陰影圖片去解除:

navigationBarApperance.shadowImage = [UIImage imageWithColor:[UIColor redColor]];

此方式設置的背景色,可以達到效果,但是效果產生的優先級比較弱沒有下面1.3的設置背景圖片高,同學們可以根據實際情況考量是否選擇此方法。

綜上,此方法可行,優先級相對弱,推薦,綜合考量使用。

1.3 通過設置setBackgroundImage進行設置:

UINavigationBar * navigationBarApperance = [UINavigationBar appearance];

[navigationBarApperance setBackgroundImage:[UIImage imageWithColor:[UIColor redColor]] forBarMetrics:UIBarMetricsDefault];


backgroundImage.png

此方法設置的導航欄底部也會有一條淺黃的分割線陰影,和上面barTintColor效果一樣,底下的分割線陰影也可以自動以設置。但是需要注意的是,此方法設置的優先級是最高的,會覆蓋掉1.1,1.2中所有設置的背景色。

驗證如下:

UINavigationBar * navigationBarApperance = [UINavigationBar appearance];

[navigationBarApperance setBackgroundImage:[UIImage imageWithColor:[UIColor whiteColor]] forBarMetrics:UIBarMetricsDefault];

navigationBarApperance.barTintColor = [UIColor redColor];

以上代碼我先設置白色背景圖,再設置紅色barTintColor,但是紅色的背景色沒有生效,還是被白色背景圖覆蓋,如下圖:


backgroundImage優先級最高.png

綜上,此方法可行,優先級最高,推薦,綜合考量使用。

這里說個查bug的小提示,當我們在某個頁面設置了導航欄背景色,但是沒有生效,這個時候我們需要檢查下是不是我們用的bartintColor設置的被父類的設置背景圖給覆蓋了,導致沒有生效,這個時候你就需要也用設置背景色來設置了。

下面我們針對前面提出的為什么設置的backgrandColor會被遮擋做出解釋。

導航欄的層級圖如下:


導航欄圖層.png

從上圖我們可以看到,導航欄一共分為4大層,分別是,

1:背景色(backgroundColor)層,在最下面

2:背景層(barbackground),用作父視圖

3:背景圖片(imageview)層,此處有2個imageview,一個是背景圖片,一個市分割線圖片

4:主內容(contentview)層,用來顯示navigationItem,比如導航欄的title,titleview,barButtonItem等。

通過層級我們可以看到,我們前面之所以設置的背景色顯示不出來,是因為這個背景色在最底層,會被上面的背景層給遮擋,個人感覺說白了,我們設置導航欄的背景色就是無用的。

2.設置導航欄上的字體顏色

2.1 設置導航欄左右兩邊barbuttonItem的顏色:tintColor

navigationBarApperance.barTintColor = [UIColor greenColor];

注意:這種方式不能改變導航欄中間標題的顏色

barbuttonItem的顏色也可以通過自定制視圖設置:

UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];

[leftBtn setTitle:@"左邊" forState:UIControlStateNormal];

[leftBtn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];

以上這種自定制設置如果設置了顏色會覆蓋掉前面設置的tintColor。

2.2 設置導航欄中間標題的顏色,字體:通過設置屬性字符串實現TitleTextAttributes

navigationBarApperance.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor redColor],NSFontAttributeName:[UIFont systemFontOfSize:18]};

這里說下,設置頁面導航欄標題的方式,有兩種:

方式一:self.title = @"首頁";

方式二:self.navigationItem.title = @"首頁";

這兩種方式都可以設置標題,而且效果是一樣的,如果這兩個方式都設置了標題,那么最后的標題會覆蓋掉前面的設置的。

3.梳理下navigationBar,navigationItem的關系

navigationBar是UINavigationController的一個屬性,主要用來設置導航欄顏色(背景色和鏤空色tintColor)

navigationItem是UIViewController的一個分類UINavigationControllerItem中的屬性,主要用來自定制導航欄上顯示的東西,包括左右兩邊的barbuttonItem,中間的title或者中間的titleview。navigationItem主要是前面介紹的導航欄層級中最上層contentview的子視圖。

三、常用設置導航欄,tabbar代碼

1.統一設置NavigationBar的顏色、tint顏色、、字體

// 設置導航欄的顏色 [[UINavigationBar appearance] setBarTintColor:[UIColor redColor]]; // 設置tint顏色 [[UINavigationBar appearance] setTintColor: [UIColor whiteColor]]; // 設置導航欄上的標題的顏色、字體 [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor redColor],NSFontAttributeName:[UIFont systemFontOfSize:18]}]; // 取消透明度 [[UINavigationBar appearance] setTranslucent:NO]; // 設置背景圖片(前面已經設置了顏色,此處可以不設置,避免覆蓋掉上面的顏色) [[UINavigationBar appearance] setBackgroundImage:xxx forBarMetrics:UIBarMetricsDefault]; // 去掉導航欄與內容之間的分割線 [self.navigationController.navigationBar setShadowImage:nil];

2、設置tabbar相關

[[UITabBar appearance] setTintColor: [UIColor blueColor]]; //Normal [[UITabBarItem appearance] setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12],NSBackgroundColorAttributeName:[UIColor greenColor]} forState:UIControlStateNormal]; //Selected [[UITabBarItem appearance] setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSBackgroundColorAttributeName:[UIColor redColor]} forState:UIControlStateSelected]; // 設置tabbar上的圖片不要用tintcolor,使用圖片原生的樣子 UIImage *normalImg = [[UIImage imageNamed:@"xxx"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; vc.tabBarItem.image = normalImg; UIImage *selectImg = [[UIImage imageNamed:@"xxx"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; vc.tabBarItem.selectedImage = selectImg; // 將tabbar的顏色設置為黑色 self.tabBar.barTintColor = [UIColor blackColor];

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容