UIButton選中狀態(tài)下的點(diǎn)擊

在類似點(diǎn)贊或切換瀏覽模式等功能的時(shí)候,需要用到button的選中狀態(tài):即點(diǎn)擊后按鈕切換圖片,并保持這個(gè)狀態(tài),直到下一次點(diǎn)擊.
如:


接下來我們就以這兩個(gè)圖片為例子.

已知點(diǎn)擊前那張圖片名字是like.png,簡(jiǎn)稱"like",
嫩綠色那張圖片名字是like_selected.png,簡(jiǎn)稱為"like_selected".

初學(xué)者可能的做法

  • 創(chuàng)建button的時(shí)候設(shè)置normal狀態(tài)下的圖片為like,點(diǎn)擊后重新設(shè)置normal狀態(tài)下的圖片為like_selected,代碼如下:
// 省略了部分非關(guān)鍵代碼
[button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];

- (void)buttonClick:(UIButton *)button {
    if ([button.currentImage isEqual:[UIImage imageNamed:@"like"]]) {
        [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateNormal];
    }
    else {
        [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
    }
}

雖然我也曾經(jīng)寫過這樣寫過(往事不堪回首...),雖然是可以勉強(qiáng)達(dá)到要求,但不得不承認(rèn),這是一段糟糕的代碼,強(qiáng)烈不建議大家使用.

進(jìn)階做法

  • 分別設(shè)置按鈕在normal和selected狀態(tài)下的圖片,點(diǎn)擊按鈕時(shí)切換按鈕的選中狀態(tài):
// 省略了部分非關(guān)鍵代碼
    [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];


- (void)buttonClick:(UIButton *)button {
    button.selected = !button.selected;
}

看起來好多了,代碼似乎也更加合理.

但是使用過這種方法的人應(yīng)該都會(huì)遇到這樣一個(gè)問題:不管按鈕從normal狀態(tài)轉(zhuǎn)為selected狀態(tài),還是反過來,中間都會(huì)經(jīng)歷一個(gè)highLighted狀態(tài),這就導(dǎo)致在狀態(tài)切換的過程中有一次圖片的跳變.如圖:

  • 改進(jìn)

    我們可能想到給button的highted狀態(tài)也設(shè)置圖片:
[button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"like"] forState: UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];

這樣設(shè)置后,按鈕從normal變?yōu)閟elected的過程看起來似乎行得通了,但是,從selected再變回normal的過程還是會(huì)出現(xiàn)那個(gè)該死的hightLighted狀態(tài).

感到奇怪吧?我們明明已經(jīng)設(shè)置了hightLighted狀態(tài)下的圖片,怎么回來的路行不通呢? 有沒有可能從selected狀態(tài)變回normal狀態(tài)這個(gè)過程經(jīng)歷的并不是hightLighted狀態(tài),而是其他什么狀態(tài)呢?

沒錯(cuò),這個(gè)狀態(tài)就是UIControlStateSelected | UIControlStateHighlighted,我們可以理解成選中時(shí)候的高亮狀態(tài).

初學(xué)的時(shí)候?qū)@個(gè)狀態(tài)不理解,還以為是同時(shí)設(shè)置選中狀態(tài)高亮狀態(tài)下的圖片,學(xué)習(xí)過程中發(fā)現(xiàn)真諦后大徹大悟.

  • 再改進(jìn)
[button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"like"] forState: UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];
[button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected | UIControlStateHighlighted];

這樣就完全達(dá)可以了,不管如何點(diǎn)擊按鈕,按鈕的圖片只顯示兩種,而且都是手指抬起來的時(shí)候改變.

更先進(jìn)一點(diǎn)的做法

  • 重寫button的setHighted:方法

我們需要自定義一個(gè)繼承自UIButton的子類,并將剛才創(chuàng)建的button類型改為我們創(chuàng)建的類型.

接著在自定義button的內(nèi)部重寫setHighted:方法

- (void)setHighlighted:(BOOL)highlighted {

}

當(dāng)然你不需要在方法里面做任何事情,這表示我們阻止了系統(tǒng)按鈕默認(rèn)的做法,屏蔽了它的高亮效果.按鈕也只需簡(jiǎn)單地設(shè)置為:

[button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];

ok,以上就是今天的全部?jī)?nèi)容.
當(dāng)然說"更先進(jìn)一點(diǎn)的做法"這種說法可能不夠準(zhǔn)確,仁者見仁嘛,也許你覺得僅為了一個(gè)高亮就不需要大費(fèi)周章地自定義一個(gè)button了.我保留意見,只要大家不要用第一種做法就好了.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔬蕊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哥谷,更是在濱河造成了極大的恐慌岸夯,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件们妥,死亡現(xiàn)場(chǎng)離奇詭異猜扮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)监婶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門旅赢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惑惶,你說我怎么就攤上這事煮盼。” “怎么了带污?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵僵控,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我鱼冀,道長(zhǎng)报破,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任雷绢,我火速辦了婚禮泛烙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翘紊。我一直安慰自己蔽氨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鹉究,像睡著了一般宇立。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上自赔,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天妈嘹,我揣著相機(jī)與錄音,去河邊找鬼绍妨。 笑死润脸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的他去。 我是一名探鬼主播毙驯,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼灾测!你這毒婦竟也來了爆价?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤媳搪,失蹤者是張志新(化名)和其女友劉穎铭段,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秦爆,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡序愚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鲜结。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片展运。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖精刷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蔗候,我是刑警寧澤怒允,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站锈遥,受9級(jí)特大地震影響纫事,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜所灸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一丽惶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爬立,春花似錦钾唬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奕巍。三九已至,卻和暖如春儒士,著一層夾襖步出監(jiān)牢的瞬間的止,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工着撩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诅福,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓拖叙,卻偏偏與公主長(zhǎng)得像权谁,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子憋沿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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