前言
過年期間,少不了各種聚會,當(dāng)下聚會大多數(shù)情況下自然是團(tuán)購,然后就是用各種APP。。。使用度娘糯米時(不是廣告,不是廣告,不是廣告!),偶然注意到了它的首頁中一個有意思的效果,就是那些“按鈕”點(diǎn)擊時的縮放動畫,有一種“按下去”的趕腳,恰逢前陣子做過一個錄音按鈕的“點(diǎn)動”效果,忍不住便封裝了這個按鈕效果:GitHub
demo中的按鈕背景圖片截取自度娘糯米首頁,僅供學(xué)習(xí)參考!
糯米首頁應(yīng)該是collectionView布局吧?也許,這里只是純粹實(shí)現(xiàn)效果,封裝了系統(tǒng)的按鈕。
關(guān)于這個效果,首先不得不提一個概念——點(diǎn)動。
1.關(guān)于“點(diǎn)動”按鈕
點(diǎn)動這一概念,我是從硬件那邊搬過來的。
曾經(jīng)做單片機(jī)時,按鍵是一個很重要的外設(shè),硬件按鍵在編寫代碼實(shí)現(xiàn)功能時,一般有兩種效果:帶鎖按鈕,不帶鎖按鈕。
所謂帶鎖按鈕,就是點(diǎn)擊按鈕之后立刻松手,就能實(shí)現(xiàn)對應(yīng)功能,例如我們曾經(jīng)用過的按鍵手機(jī)的數(shù)字鍵都是這樣的。
所謂不帶鎖按鈕,也就是這里要說的“點(diǎn)動”,顧名思義,就是點(diǎn)擊就動,松手即停。單片機(jī)那邊一般在電機(jī)控制什么的場景經(jīng)常用到,在我們軟件這邊,較普遍的一個應(yīng)用場景就是“錄音按鈕”(微信語音神馬的)。
錄音按鈕在點(diǎn)擊時進(jìn)行錄音,一旦松手,錄音就會停止。
為了便于說明,寫了以下效果進(jìn)行演示,button的showsTouchWhenHighlighted
屬性打開以指示按鈕正在被點(diǎn)擊中。
2.實(shí)現(xiàn)“點(diǎn)動”按鈕
實(shí)現(xiàn)按鈕的“點(diǎn)動”其實(shí)很簡單:
//按下時
[myButton addTarget:self
action:@selector(pressedEvent:)
forControlEvents:UIControlEventTouchDown];
//松手后
[myButton addTarget:self
action:@selector(unpressedEvent:)
forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
接下來在按鈕的點(diǎn)擊響應(yīng)實(shí)現(xiàn)中:
- (void)pressedEvent:(id)sender
實(shí)現(xiàn)的是按鈕按下的響應(yīng),例如錄音開始并持續(xù)。
- (void)unpressedEvent:(id)sender
則實(shí)現(xiàn)的是松開按鈕(停止點(diǎn)擊)時的響應(yīng),此時執(zhí)行結(jié)束錄音。
兩個響應(yīng)結(jié)合起來,也就實(shí)現(xiàn)了硬件按鈕的“點(diǎn)動”效果(硬件按鍵是根據(jù)高低電平判定的,所以代碼實(shí)現(xiàn)十分簡單,對單片機(jī)有興趣的朋友可以查閱相關(guān)資料,不過硬件按鍵按下時的電平“抖動”則是十分令人頭疼的問題)。
這里還要提一點(diǎn),就是ControlEvents
,這里寫的是UIControlEventTouchUpInside | UIControlEventTouchUpOutside
,意思就是在按鈕區(qū)域范圍內(nèi)或者范圍外(按下之后,手指移動拖移)松手(停止點(diǎn)擊),都會執(zhí)行“松手響應(yīng)”,這在一些情況下要注意區(qū)分,例如接下來要實(shí)現(xiàn)的“縮放按鈕”。如果我們只寫UIControlEventTouchUpInside
,那么,我們在按鈕區(qū)域范圍外松手,也就是點(diǎn)擊之后,手指拖動,移到按鈕frame外,unpressedEvent
響應(yīng)是不執(zhí)行的,我們從而也就實(shí)現(xiàn)了一個“取消”效果,當(dāng)然這個不是用在錄音按鈕中的。
3.動畫縮放按鈕
前面啰嗦了一大堆,現(xiàn)在切入正題,其實(shí),正題也就沒什么要說的了,實(shí)現(xiàn)糯米的這一效果,無非還是上面的“動作拆分”思想,我們只要將按鈕按下的縮放動畫,以及動畫執(zhí)行之后的真正的響應(yīng),分別寫在兩個響應(yīng)函數(shù)中就可以了。
//按鈕的按下事件 按鈕縮小
- (void)pressedEvent:(JXTPushInButton *)btn
{
//縮放比例必須大于0,且小于等于1
CGFloat scale = (_buttonScale && _buttonScale <=1.0) ? _buttonScale : defaultScale;//defaultScale默認(rèn)為0.9
[UIView animateWithDuration:animateDelay animations:^{
btn.transform = CGAffineTransformMakeScale(scale, scale);
}];
}
//按鈕的松開事件 按鈕復(fù)原 執(zhí)行響應(yīng)
- (void)unpressedEvent:(JXTPushInButton *)btn
{
[UIView animateWithDuration:animateDelay animations:^{
btn.transform = CGAffineTransformMakeScale(1.0, 1.0);
} completion:^(BOOL finished) {
//執(zhí)行動作響應(yīng)
if (self.clickBlock) {
self.clickBlock();
}
}];
}
按鈕按下真正要執(zhí)行的響應(yīng),封裝在了block中,button的封裝詳見我傳到github中的代碼,調(diào)用很方便,還是一句話:
JXTPushInButton * btn = [JXTPushInButton touchUpOutsideCancelButtonWithType:UIButtonTypeCustom frame:CGRectMake(0, 0, ScreenWidth - 20, 80) title:@"按鈕-1" titleColor:[UIColor blackColor] backgroundColor:[UIColor redColor] backgroundImage:nil andBlock:^{
NSLog(@"frame內(nèi)部松手執(zhí),行按鈕-1");
}];
[self.view addSubview:btn];
參考文章:
1.UIButton---按住錄音,松開停止
2.iOS下UIButton壓下后播放動畫,松開后動畫消失的實(shí)現(xiàn)