iOS:弱者與“按鈕形狀”/返回按鈕

前言:弱者為什么執拗?


? ? 大三下在學swift的時候,給一款APP建過言,說他的APP返回按鈕在按鈕形狀下是一團,換成圖片就好了。當時沒學多久,想的也十分天真。對方很給力,下個版本就改了。等到自己學Objective-c實習遇到這個問題的時候,發現用圖片的確可以,但是有個新問題,返回手勢不起作用了!這就很尷尬了!我一定要與“按鈕形狀”斗爭到底!

按鈕形狀


? ? iOS在7.1版本出的按鈕形狀,目的是為了讓按鈕更加顯眼。


1.png


2,png
3.png

圖1~3分別是按鈕、UIBarButtonItem、TabBar的普通狀態和按鈕形狀狀態,可以輕松的發現,按鈕的按鈕形狀是文字下面多了個下劃線,UIBarButtonItem和TabBar仿佛是多了個背景顏色。

返回按鈕


? ? 我在實習的時候,項目一剛開始是這么解決返回按鈕的:

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0,-60)forBarMetrics:UIBarMetricsDefault];

把返回按鈕的title上移60,移除屏幕,就剩下一個返回圖標。這個方法在非按鈕形狀下顯示沒問題,在按鈕形狀下,返回按鈕就是一團,如圖4,顯然不怎么美觀,尤其是當父控制器title比較長的時候。


4.png

? ? 之后我嘗試了多種辦法,比如,在父控制器push子控制器的時候,把父控制器的title設置為空,但是當pop回來時發現上一級控制器title沒了(當然了,你把它設置為空的);改進,在子控制器viewWillAppear的時候把設置自己的title,在父控制器viewDidDisapper的時候把父控制器title設置為空(要判斷是push還是pop,為什么就不說了,反正也不用這個方法),缺點是返回按鈕會閃一下;把返回按鈕換成圖片,缺點是側滑返回手勢沒了。為此我還研究了其他很多APP的返回按鈕、TabBar、UIBarButtonItem,依然沒有結果。

? ? 沒辦法,只好去看本地頭文件里面簡短的介紹、官方API文檔。發現如下幾個東西:backItem、backBarButtonItem、navigationItem.title、navigationController.title、viewController.title。

backItem,只讀,先不管。

對于backBarButtonItem,頭文件中注釋說:

Bar button item to use for the back button in the child navigation item.

用于子控制器的返回按鈕。哇塞,一臉懵逼,從來沒用過這個呀。繼續看。

對于navigationItem.title,頭文件中注釋說:

Title when topmost on the stack. default is nil

當控制器在棧頂的時候顯示的標題,默認為空。說的十分明白。

對于navigationController.title,不好意思這個用command+左鍵找到的是UIAlertController.title,viewController.title點進去也是一樣的,原來navigationController的繼承ViewController的,可能鏈接有點錯誤。

對于viewController.title,頭文件中注釋說

Localized title for use by a parent controller.

懵逼,去看看官方開發者API文檔吧。

? ? 先看backBarButtonItem,翻一下就是:的確是用來設置子控制器的返回按鈕,在當其需要一個返回按鈕的時候。但默認為空。當它為空的時候,會用navigationItem的title屬性來建一個返回按鈕,如果你想自定義圖片或者標題的返回按鈕,你可以賦值一個普通的BarButtonItem給backBarButtonItem來替換。

? ? 說的很明白,順著它給的超鏈接來看navigationItem.title,翻一下:說它擺在navigationBar的中間,默認為空。當一個控制器有子控制器,并且navigationItem.title為空的時候哇,系統會用“back”來作為子控制器返回按鈕的text。

? ? 也許你平時是直接對viewController.title或者navigationController.title進行賦值,發現顯示也是沒問題的,同時影響著父控制器頂部導航欄標題和子控制器的返回按鈕的標題,這又是怎么回事呢?

你可以在UINavigationControllerThe Left Item完善對返回按鈕的認識,在The Middle Item可以看到對titleView、title的解釋,我們重點來看title。翻一下:如果沒有設置自定義titleView,那么navigation bar就是展示一個label包含viewController的默認標題。這個標題是從自己的viewController的title屬性獲取的,如果你想自定義,你可以設置navigationItem的title屬性。

最后來到了UIViewController.title,翻一下:用人可讀的語言設置title來描述你的view,如果viewController有navigation item 或者 tab-bar item,那么會都影響這個兩個的title。UINavigationController.title官方直接超鏈接的是UIViewController.title,故不建議對UINavigationController.title進行操作,如有需要,可以對UIViewController.title進行操作。

好了,到了這,也許有點亂,理一下。ViewController的title屬性無疑擁有最高影響力,它影響自己控制的navigation item 和 tab-bar item的title;navigation item的title默認為空,會先受titleView的影響,如果沒有自定義titleView才顯示ViewController.title,你也可以設置navigationItem.title來自定義標題,最終顯示后設置的那個標題。backBarButtonItem默認為空,子控制器的返回按鈕的title受其影響,當其為空時,返回按鈕會去找navigation item的title,navigation item的title也為空是,會顯示“back”,中文顯示“返回”。

問:自定義了titleView,同時設置了navigationItem.title或者viewController.title,請問父控制器頂部導航欄顯示誰的標題?子控制器的返回按鈕顯示什么title。

答:父控制器顯示自定義titleView的,子控制器返回按鈕顯示navigationItem.title或者viewController.title。

OK,說了這么多,為了達到我們初始目的,只需要自定義一個UIBarButtonItem賦值給父控制器的backBarButtonItem就行了!經測試,只有title有效,action、Target無效。有空的同學可以嘗試用- (instancetype)initWithCustomView:(UIView*)customView;來自定義返回按鈕樣式,反正我沒嘗試成功。

那么,我們在平時開發中應該對哪個設置標題呢?看下官方建議或者打開你的storyBoard:


5.png

如圖5,官方建議是對NavigationItem進行設置,當你額外需要,你可以設置TitleView給NavigationItem,比如帶屬性的文字、把title變成一個可交互的Button等等。

Button、TabBar和UIBarButtonItem


解決完返回按鈕,還剩下button、TabBar和UIBarButtonItem的按鈕形狀。實習的時候,由于找不到方法解決“按鈕形狀”,一是問題不好描述,二是關注的人少,我一度認為按鈕形狀狀態下有下劃線的就是Button,背景有顏色的就是UIBarButtonItem、TabBar,因此我一度認為微博、淘寶等客戶端是完全自定義了NavigationController、TabBarController,前者導航欄上的Item沒有下劃線、也沒有背景顏色,后者導航欄全都是下劃線,前者底部TabBar有下劃線沒有背景顏色,難道是用的Button?真不愧大牛啊!當然也有客戶TabBar在按鈕形狀狀態下不顯示背景顏色、也沒有下劃線的,說明還是有方法的,更加堅定了我繼續研究的決心。

一次偶然的機會,我用Reveal發現了TabBar在按鈕形狀下顯示背景顏色的view:


6.png

我欣喜若狂,只要把這個View設置一個透明色不就好了,然后我就去找這個View,很遺憾,沒找到,卻找到了selectionIndicatorImage,肯定是親戚!趕緊設置TabBarButton:

self.selectionIndicatorImage = [UIImage new];

我是自定義的TabBar,所以這樣設置的。一運行,哈哈,背景顏色果然不見了!什么原理呢?

看下官方解釋吧selectionIndicatorImage,翻一下:用這個屬性來自定義選擇圖片,你的圖片將顯示在TabBar底部但是呢隱藏在TabBar的Contents的下面。默認為空,當為空時,被選定時就是顯示高亮。沒跑了就是它,選擇指示器圖片,但是官方也沒提按鈕形狀。我們可以用它來做點選中TabBar的效果。那么其他兩個呢?


7.png

用Reveal看按鈕,就看不出什么鬼了,怎么辦呢?TabBar是因為設置了一個Image,那么Button呢會不會也這樣呢?抱著試一試的心態:

[testButton setBackgroundImage:[UIImage new] forState:UIControlStateNormal];

然后,然后下劃線就沒了!!!怎么回事?官方的對背景圖片的說明也未提及按鈕形狀/下劃線/高亮,可能和TabBar差不多吧。那么對于UIBarButtonItem只需要initWithCustomView:一個帶有背景圖片的button,那么在按鈕形狀下就不再有背景顏色了。有種戛然而止的感覺。

總結


1、子控制器的返回按鈕title優先來自父控制器的backBarButtonItem.title;

2、backBarButtonItem默認為空,當其為空,返回按鈕就去找NavigationItem.title;

3、ViewController.title會同時影響NavigationItem.title、tabBar的title,如果有的話;

4、針對第三點,后設置的那個會最終顯示出來

5、針對第二點,當NavigationItem.title也為空時,返回按鈕顯示“back”,中文“返回”;

6、當backBarButtonItem.title為空字符串時,子控制器返回按鈕只顯示圖標,并且沒有按鈕形狀下的一塊背景顏色(修改NavigationItem的title不建議);

7、要修改控制器的頂部導航欄標題建議對NavigationItem.title進行修改;

8、去除TabBar的按鈕形狀設置它的selectionIndicatorImage;

9、去除UIButton的按鈕形狀,setBackgroundImage:[UIImage new] forState:UIControlStateNormal;

10、去除UIBarButtonItem的按鈕形狀,initWithCustomView:一個帶有背景圖片的button即可;


后記


寫完了,越寫到后面越發現一股弱者的氣息,希望能幫到人。拜了個拜。@徐星星去哪了

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容