在類似點(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了.我保留意見,只要大家不要用第一種做法就好了.