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

前言:弱者為什么執(zhí)拗榕茧?


? ? 大三下在學(xué)swift的時候,給一款A(yù)PP建過言客给,說他的APP返回按鈕在按鈕形狀下是一團(tuán)用押,換成圖片就好了。當(dāng)時沒學(xué)多久起愈,想的也十分天真只恨。對方很給力,下個版本就改了抬虽。等到自己學(xué)Objective-c實習(xí)遇到這個問題的時候官觅,發(fā)現(xiàn)用圖片的確可以,但是有個新問題阐污,返回手勢不起作用了休涤!這就很尷尬了!我一定要與“按鈕形狀”斗爭到底笛辟!

按鈕形狀


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


1.png


2手幢,png
3.png

圖1~3分別是按鈕捷凄、UIBarButtonItem、TabBar的普通狀態(tài)和按鈕形狀狀態(tài)围来,可以輕松的發(fā)現(xiàn)跺涤,按鈕的按鈕形狀是文字下面多了個下劃線,UIBarButtonItem和TabBar仿佛是多了個背景顏色监透。

返回按鈕


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

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

把返回按鈕的title上移60,移除屏幕胀蛮,就剩下一個返回圖標(biāo)院刁。這個方法在非按鈕形狀下顯示沒問題,在按鈕形狀下粪狼,返回按鈕就是一團(tuán)退腥,如圖4,顯然不怎么美觀再榄,尤其是當(dāng)父控制器title比較長的時候狡刘。


4.png

? ? 之后我嘗試了多種辦法,比如不跟,在父控制器push子控制器的時候颓帝,把父控制器的title設(shè)置為空,但是當(dāng)pop回來時發(fā)現(xiàn)上一級控制器title沒了(當(dāng)然了,你把它設(shè)置為空的)购城;改進(jìn)吕座,在子控制器viewWillAppear的時候把設(shè)置自己的title,在父控制器viewDidDisapper的時候把父控制器title設(shè)置為空(要判斷是push還是pop瘪板,為什么就不說了吴趴,反正也不用這個方法),缺點(diǎn)是返回按鈕會閃一下;把返回按鈕換成圖片侮攀,缺點(diǎn)是側(cè)滑返回手勢沒了锣枝。為此我還研究了其他很多APP的返回按鈕、TabBar兰英、UIBarButtonItem撇叁,依然沒有結(jié)果。

? ? 沒辦法畦贸,只好去看本地頭文件里面簡短的介紹陨闹、官方API文檔。發(fā)現(xiàn)如下幾個東西:backItem薄坏、backBarButtonItem趋厉、navigationItem.title、navigationController.title胶坠、viewController.title君账。

backItem,只讀沈善,先不管乡数。

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

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

用于子控制器的返回按鈕矮瘟。哇塞瞳脓,一臉懵逼塑娇,從來沒用過這個呀澈侠。繼續(xù)看。

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

Title when topmost on the stack. default is nil

當(dāng)控制器在棧頂?shù)臅r候顯示的標(biāo)題哨啃,默認(rèn)為空。說的十分明白写妥。

對于navigationController.title拳球,不好意思這個用command+左鍵找到的是UIAlertController.title,viewController.title點(diǎn)進(jìn)去也是一樣的珍特,原來navigationController的繼承ViewController的,可能鏈接有點(diǎn)錯誤祝峻。

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

Localized title for use by a parent controller.

懵逼,去看看官方開發(fā)者API文檔吧莱找。

? ? 先看backBarButtonItem,翻一下就是:的確是用來設(shè)置子控制器的返回按鈕酬姆,在當(dāng)其需要一個返回按鈕的時候。但默認(rèn)為空奥溺。當(dāng)它為空的時候辞色,會用navigationItem的title屬性來建一個返回按鈕,如果你想自定義圖片或者標(biāo)題的返回按鈕浮定,你可以賦值一個普通的BarButtonItem給backBarButtonItem來替換相满。

? ? 說的很明白,順著它給的超鏈接來看navigationItem.title,翻一下:說它擺在navigationBar的中間桦卒,默認(rèn)為空立美。當(dāng)一個控制器有子控制器,并且navigationItem.title為空的時候哇方灾,系統(tǒng)會用“back”來作為子控制器返回按鈕的text悯辙。

? ? 也許你平時是直接對viewController.title或者navigationController.title進(jìn)行賦值,發(fā)現(xiàn)顯示也是沒問題的迎吵,同時影響著父控制器頂部導(dǎo)航欄標(biāo)題和子控制器的返回按鈕的標(biāo)題躲撰,這又是怎么回事呢?

你可以在UINavigationControllerThe Left Item完善對返回按鈕的認(rèn)識击费,在The Middle Item可以看到對titleView拢蛋、title的解釋,我們重點(diǎn)來看title蔫巩。翻一下:如果沒有設(shè)置自定義titleView谆棱,那么navigation bar就是展示一個label包含viewController的默認(rèn)標(biāo)題。這個標(biāo)題是從自己的viewController的title屬性獲取的圆仔,如果你想自定義垃瞧,你可以設(shè)置navigationItem的title屬性。

最后來到了UIViewController.title,翻一下:用人可讀的語言設(shè)置title來描述你的view坪郭,如果viewController有navigation item 或者 tab-bar item个从,那么會都影響這個兩個的title。UINavigationController.title官方直接超鏈接的是UIViewController.title歪沃,故不建議對UINavigationController.title進(jìn)行操作嗦锐,如有需要,可以對UIViewController.title進(jìn)行操作沪曙。

好了奕污,到了這,也許有點(diǎn)亂液走,理一下碳默。ViewController的title屬性無疑擁有最高影響力贾陷,它影響自己控制的navigation item 和 tab-bar item的title;navigation item的title默認(rèn)為空嘱根,會先受titleView的影響昵宇,如果沒有自定義titleView才顯示ViewController.title,你也可以設(shè)置navigationItem.title來自定義標(biāo)題儿子,最終顯示后設(shè)置的那個標(biāo)題瓦哎。backBarButtonItem默認(rèn)為空,子控制器的返回按鈕的title受其影響柔逼,當(dāng)其為空時蒋譬,返回按鈕會去找navigation item的title,navigation item的title也為空是愉适,會顯示“back”犯助,中文顯示“返回”。

問:自定義了titleView维咸,同時設(shè)置了navigationItem.title或者viewController.title剂买,請問父控制器頂部導(dǎo)航欄顯示誰的標(biāo)題?子控制器的返回按鈕顯示什么title癌蓖。

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

OK租副,說了這么多坐慰,為了達(dá)到我們初始目的,只需要自定義一個UIBarButtonItem賦值給父控制器的backBarButtonItem就行了用僧!經(jīng)測試结胀,只有title有效,action责循、Target無效糟港。有空的同學(xué)可以嘗試用- (instancetype)initWithCustomView:(UIView*)customView;來自定義返回按鈕樣式,反正我沒嘗試成功院仿。

那么秸抚,我們在平時開發(fā)中應(yīng)該對哪個設(shè)置標(biāo)題呢?看下官方建議或者打開你的storyBoard:


5.png

如圖5意蛀,官方建議是對NavigationItem進(jìn)行設(shè)置耸别,當(dāng)你額外需要健芭,你可以設(shè)置TitleView給NavigationItem县钥,比如帶屬性的文字、把title變成一個可交互的Button等等慈迈。

Button若贮、TabBar和UIBarButtonItem


解決完返回按鈕省有,還剩下button、TabBar和UIBarButtonItem的按鈕形狀谴麦。實習(xí)的時候蠢沿,由于找不到方法解決“按鈕形狀”,一是問題不好描述匾效,二是關(guān)注的人少舷蟀,我一度認(rèn)為按鈕形狀狀態(tài)下有下劃線的就是Button,背景有顏色的就是UIBarButtonItem面哼、TabBar野宜,因此我一度認(rèn)為微博、淘寶等客戶端是完全自定義了NavigationController魔策、TabBarController匈子,前者導(dǎo)航欄上的Item沒有下劃線、也沒有背景顏色闯袒,后者導(dǎo)航欄全都是下劃線虎敦,前者底部TabBar有下劃線沒有背景顏色,難道是用的Button政敢?真不愧大牛捌溽恪!當(dāng)然也有客戶TabBar在按鈕形狀狀態(tài)下不顯示背景顏色喷户、也沒有下劃線的擂橘,說明還是有方法的,更加堅定了我繼續(xù)研究的決心摩骨。

一次偶然的機(jī)會通贞,我用Reveal發(fā)現(xiàn)了TabBar在按鈕形狀下顯示背景顏色的view:


6.png

我欣喜若狂,只要把這個View設(shè)置一個透明色不就好了恼五,然后我就去找這個View昌罩,很遺憾,沒找到灾馒,卻找到了selectionIndicatorImage茎用,肯定是親戚!趕緊設(shè)置TabBarButton:

self.selectionIndicatorImage = [UIImage new];

我是自定義的TabBar睬罗,所以這樣設(shè)置的轨功。一運(yùn)行,哈哈容达,背景顏色果然不見了古涧!什么原理呢?

看下官方解釋吧selectionIndicatorImage花盐,翻一下:用這個屬性來自定義選擇圖片羡滑,你的圖片將顯示在TabBar底部但是呢隱藏在TabBar的Contents的下面菇爪。默認(rèn)為空,當(dāng)為空時柒昏,被選定時就是顯示高亮凳宙。沒跑了就是它,選擇指示器圖片职祷,但是官方也沒提按鈕形狀氏涩。我們可以用它來做點(diǎn)選中TabBar的效果。那么其他兩個呢有梆?


7.png

用Reveal看按鈕削葱,就看不出什么鬼了,怎么辦呢淳梦?TabBar是因為設(shè)置了一個Image析砸,那么Button呢會不會也這樣呢?抱著試一試的心態(tài):

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

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

總結(jié)


1啸罢、子控制器的返回按鈕title優(yōu)先來自父控制器的backBarButtonItem.title;

2胎食、backBarButtonItem默認(rèn)為空扰才,當(dāng)其為空,返回按鈕就去找NavigationItem.title厕怜;

3衩匣、ViewController.title會同時影響NavigationItem.title、tabBar的title粥航,如果有的話琅捏;

4、針對第三點(diǎn)递雀,后設(shè)置的那個會最終顯示出來

5柄延、針對第二點(diǎn),當(dāng)NavigationItem.title也為空時映之,返回按鈕顯示“back”拦焚,中文“返回”蜡坊;

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

7僵刮、要修改控制器的頂部導(dǎo)航欄標(biāo)題建議對NavigationItem.title進(jìn)行修改;

8鹦牛、去除TabBar的按鈕形狀設(shè)置它的selectionIndicatorImage搞糕;

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

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


后記


寫完了,越寫到后面越發(fā)現(xiàn)一股弱者的氣息晶伦,希望能幫到人碟狞。拜了個拜。@徐星星去哪了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婚陪,一起剝皮案震驚了整個濱河市族沃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泌参,老刑警劉巖脆淹,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沽一,居然都是意外死亡未辆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門锯玛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咐柜,“玉大人藕畔,你說我怎么就攤上這事犁罩。” “怎么了背苦?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵歼郭,是天一觀的道長遗契。 經(jīng)常有香客問我,道長病曾,這世上最難降的妖魔是什么牍蜂? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任漾根,我火速辦了婚禮,結(jié)果婚禮上鲫竞,老公的妹妹穿的比我還像新娘辐怕。我一直安慰自己,他們只是感情好从绘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布寄疏。 她就那樣靜靜地躺著,像睡著了一般僵井。 火紅的嫁衣襯著肌膚如雪陕截。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天批什,我揣著相機(jī)與錄音农曲,去河邊找鬼。 笑死驻债,一個胖子當(dāng)著我的面吹牛乳规,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播却汉,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼驯妄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了合砂?” 一聲冷哼從身側(cè)響起青扔,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翩伪,沒想到半個月后微猖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缘屹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年凛剥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轻姿。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡犁珠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出互亮,到底是詐尸還是另有隱情犁享,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布豹休,位于F島的核電站炊昆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凤巨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一视乐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敢茁,春花似錦佑淀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽独榴。三九已至僧叉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棺榔,已是汗流浹背瓶堕。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留症歇,地道東北人郎笆。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像忘晤,于是被迫代替她去往敵國和親宛蚓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容