iOS黑科技【動(dòng)畫特效篇】第四期
本期帶來(lái)一款實(shí)用性強(qiáng)同時(shí)又具備高B格的控件--浮動(dòng)按鈕,實(shí)現(xiàn)原理也不復(fù)雜,短短幾行代碼就能帶來(lái)非常出色的用戶體驗(yàn)!

git來(lái)一波,和系統(tǒng)button創(chuàng)建方法一模一樣,簡(jiǎn)單實(shí)用:
https://github.com/XMDashen/XMMovableButtonDemo.git
原理解析:
浮動(dòng)按鈕和系統(tǒng)按鈕的最大區(qū)別就是一個(gè)可以移動(dòng),而另一個(gè)不可以...囧
所以要實(shí)現(xiàn)按鈕的移動(dòng),直接繼承UIButton,在button監(jiān)聽觸摸移動(dòng)事件里實(shí)現(xiàn)就可以啦
基本思路是將前后兩次觸摸移動(dòng)的偏移量設(shè)置到button上,如果沒有移動(dòng)偏移量則判斷為點(diǎn)擊,調(diào)用點(diǎn)擊事件
//移動(dòng)時(shí)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
UITouch * touch = [touches anyObject];
//本次觸摸點(diǎn)
CGPoint current = [touch locationInView:self];
//上次觸摸點(diǎn)
CGPoint previous = [touch previousLocationInView:self];
CGPoint center = self.center;
//中心點(diǎn)移動(dòng)觸摸移動(dòng)的距離
center.x += current.x - previous.x;
center.y += current.y - previous.y;
//限制移動(dòng)范圍
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat xMin = self.frame.size.width * 0.5f;
CGFloat xMax = screenWidth - xMin;
CGFloat yMin = self.frame.size.height * 0.5f+64;
CGFloat yMax = screenHeight - self.frame.size.height * 0.5f - 49;
if (center.x > xMax) center.x = xMax;
if (center.x < xMin) center.x = xMin;
if (center.y > yMax) center.y = yMax;
if (center.y < yMin) center.y = yMin;
self.center = center;
//移動(dòng)距離大于0.5才判斷為移動(dòng)了(提高容錯(cuò)性)
if (current.x-previous.x>=0.5 || current.y - previous.y>=0.5) {
self.isMoved = YES;
}
}
注意要限制button的移動(dòng)范圍不要超出屏幕拉不回來(lái)了。
用isMoved來(lái)記錄button的移動(dòng)狀態(tài),判斷是否移動(dòng),為了提高容錯(cuò)性將移動(dòng)距離判定為0.5用戶體驗(yàn)較好(否則有時(shí)點(diǎn)擊會(huì)產(chǎn)生微小的移動(dòng),判斷為移動(dòng)導(dǎo)致點(diǎn)擊失效,用戶會(huì)不高興的(??ˇ?ˇ??))。
//是否移動(dòng)
@property (nonatomic,assign) BOOL isMoved;
//移動(dòng)結(jié)束時(shí)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (!self.isMoved) {
//如果沒有移動(dòng),則調(diào)用父類方法,觸發(fā)button的點(diǎn)擊事件
[super touchesEnded:touches withEvent:event];
}
self.isMoved = NO;
//回到一定范圍
// CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
// CGFloat x = self.frame.size.width * 0.5f;
//
// [UIView animateWithDuration:0.25f animations:^{
// CGPoint center = self.center;
// center.x = self.center.x > screenWidth * 0.5f ? screenWidth - x : x;
// self.center = center;
// }];
//關(guān)閉高亮狀態(tài)
[self setHighlighted:NO];
}
中間注釋掉的實(shí)現(xiàn)的是button自動(dòng)滾到屏幕邊沿的功能(如阿里旺旺的懸浮球),靠近屏幕哪邊就會(huì)自動(dòng)滾到屏幕那邊,不會(huì)影響用戶屏幕中央的操作。
注意關(guān)閉按鈕高亮,否則點(diǎn)擊后會(huì)很難看,影響用戶體驗(yàn)。
這一期就到這里了,親們有什么意見和問題記得及時(shí)反饋哦,喜歡的話點(diǎn)個(gè)關(guān)注給個(gè)贊(づ ̄3 ̄)づ╭?~
我們下期再會(huì)