iOS之懸浮按鈕(自定義拖拽、自動(dòng)吸附、可約束邊界)

這幾天閑下來,整理下了之前項(xiàng)目中使用的懸浮按鈕

大致需求如下:

全屏或可約束平移;

自動(dòng)吸附,靠左或靠右吸附,類似iPhone手機(jī)中的輔助觸控的懸浮按鈕;

有的還有進(jìn)度加載等等... ? ?? 產(chǎn)品??

大致示意圖

整個(gè)功能的核心代碼就只有70行左右。


h文件



/// 平移 手勢回調(diào)

- (void)handlePan:(UIPanGestureRecognizer*)sender {

? ? if(sender.state == UIGestureRecognizerStateChanged){

?? ? ? ? {

? ? ? ? ? CGPointtranslation = [sendertranslationInView:[selfsuperview]];

? ? ? ? ? CGFloatnewXOrigin =CGRectGetMinX(self.frame) + translation.x;

? ? ? ? ? CGFloatnewYOrigin =CGRectGetMinY(self.frame) + translation.y;

? ? ? ? ? CGRectcagingArea =self.cagingArea;

? ? ? ? ? CGFloatcagingAreaOriginX =CGRectGetMinX(cagingArea);

? ? ? ? ? CGFloatcagingAreaOriginY =CGRectGetMinY(cagingArea);

? ? ? ? ? CGFloatcagingAreaRightSide = cagingAreaOriginX +CGRectGetWidth(cagingArea);

? ? ? ? ? CGFloatcagingAreaBottomSide = cagingAreaOriginY +CGRectGetHeight(cagingArea);

? ? ? ? ? if(!CGRectEqualToRect(cagingArea,CGRectZero)) {

? ? ? ? ? ? ? if(newXOrigin <= cagingAreaOriginX ||

? ? ? ? ? ? ? ? ? newXOrigin +CGRectGetWidth(self.frame) >= cagingAreaRightSide) {

? ? ? ? ? ? ? ? ? newXOrigin =CGRectGetMinX(self.frame);

? ? ? ? ? ? ? }

? ? ? ? ? ? ? if(newYOrigin <= cagingAreaOriginY ||

?? ? ? ? ? ? ? ? newYOrigin +CGRectGetHeight(self.frame) >= cagingAreaBottomSide) {

? ? ? ? ? ? ? ? ? newYOrigin =CGRectGetMinY(self.frame);

? ? ? ? ? ? ? }

? ? ? ? ? }

?? ? ? ? ? ? self.frame=CGRectMake(newXOrigin,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? newYOrigin,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CGRectGetWidth(self.frame),

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CGRectGetHeight(self.frame));

? ? ? ? ? ? ? ? [sendersetTranslation:(CGPoint){0,0}inView:[selfsuperview]];


?? ? ? ? }


? ? }else if (sender.state == UIGestureRecognizerStateEnded){


? ? ? ? CGSizedragBtnSize =self.frame.size;

? ? ? ? CGFloatdragBtn_Y =CGRectGetMinY(self.frame);

? ? ? ? CGFloatdragBtn_X =0;

? ? ? ? CGFloat? duration =0.7;//默認(rèn)時(shí)間

? ? ? ? //計(jì)算出按鈕距離邊界的差 用作動(dòng)畫時(shí)間的計(jì)算

? ? ? ? CGFloatdifference =1.0;

? ? ? ? switch(_remainStyle) {

? ? ? ? ? ? case MSDragButtonRemainStyleNone:

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? case MSDragButtonRemainStyleAutomaticMargin:

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(self.center.x>=self.cagingArea.size.width/2.0) {

?? ? ? ? ? ? ? ? ? //右

? ? ? ? ? ? ? ? ? ? dragBtn_X =self.cagingArea.size.width- dragBtnSize.width;

? ? ? ? ? ? ? ? ? ? difference =? (self.cagingArea.size.width-CGRectGetMaxX(self.frame)) /? self.cagingArea.size.width;

? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? //左

? ? ? ? ? ? ? ? ? ? dragBtn_X =0;

? ? ? ? ? ? ? ? ? ? difference =? CGRectGetMidX(self.frame) /? self.cagingArea.size.width;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MSDragButtonRemainStyleAutomaticMarginLeft:

? ? ? ? ? ? ? ? dragBtn_X =0;

? ? ? ? ? ? ? ? difference =? CGRectGetMidX(self.frame) /? self.cagingArea.size.width;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MSDragButtonRemainStyleAutomaticMarginRight:


?? ? ? ? ? ? ? dragBtn_X =self.cagingArea.size.width- dragBtnSize.width;

? ? ? ? ? ? ? ? difference =? (self.cagingArea.size.width-CGRectGetMaxX(self.frame)) /? self.cagingArea.size.width;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? //距離越近。動(dòng)畫時(shí)間就越短

? ? ? ? duration? = duration * difference;

? ? ? ? [UIView animateWithDuration:duration animations:^{

? ? ? ? ? ? self.frame=CGRectMake(dragBtn_X, dragBtn_Y, dragBtnSize.width, dragBtnSize.height);

? ? ? ? }];

? ? }

}

demo中沒有實(shí)現(xiàn)點(diǎn)擊事件,和隱藏相關(guān)代碼,可自行根據(jù)需求添加即可

如果能幫到你,請給個(gè)小星星

demo地址:https://github.com/marsdan/MSDragButton

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容