iOS懸浮在應用首頁可吸附在邊緣的小按鈕

類似於蘋果手機首頁那個半透明的懸浮小按鈕。

簡單來講,就是先定義一個按鈕,然後添加移動手勢UIPanGestureRecognizer,通過手勢移動狀態(Began、Changed、Ended)來控制按鈕的位置、以及吸附在哪個邊緣。

我個人目前的實現方法就是先定義一個控制器,在該控制其中添加懸浮按鈕,然後讓需要用到按鈕的控制器繼承該控制器。

懸浮小按鈕可以是任意的UIView子類視圖。

直接來看代碼吧!

//設置懸浮按鈕
- (void)configSuspendButton
{
    self.spButton = ({
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setImage:[UIImage imageNamed:@"suspendImage"] forState:UIControlStateNormal];
        btn.frame = CGRectMake(susScreenW - kSuspendBtnWidth, 200, kSuspendBtnWidth, kSuspendBtnWidth);
        // 按鈕點擊事件
        [btn addTarget:self action:@selector(suspendBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        btn.backgroundColor = [UIColor clearColor];
        // 禁止高亮
        btn.adjustsImageWhenHighlighted = NO;
        // 置頂(只是顯示置頂,但響應事件會被後來者覆蓋!)
        btn.layer.zPosition = 1;
        btn;
    });
}

在按鈕上面添加了一個移動手勢UIPanGestureRecognizer

//創建移動手勢事件
UIPanGestureRecognizer *panRcognize=[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
[panRcognize setMinimumNumberOfTouches:1];
[panRcognize setEnabled:YES];
[panRcognize delaysTouchesEnded];
[panRcognize cancelsTouchesInView];
[self.spButton addGestureRecognizer:panRcognize];

移動手勢事件處理(最主要的一段代碼)

/*
 *  懸浮按鈕移動事件處理
 */
- (void)handlePanGesture:(UIPanGestureRecognizer *)recognizer
{
    //移動狀態
    UIGestureRecognizerState recState =  recognizer.state;

    switch (recState) {
        case UIGestureRecognizerStateBegan:

            break;
        case UIGestureRecognizerStateChanged:
        {
            CGPoint translation = [recognizer translationInView:self.navigationController.view];
            recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
        }
            break;
        case UIGestureRecognizerStateEnded:
        {
            CGPoint stopPoint = CGPointMake(0, susScreenH / 2.0);

            if (recognizer.view.center.x < susScreenW / 2.0) {
                if (recognizer.view.center.y <= susScreenH/2.0) {
                    //左上
                    if (recognizer.view.center.x  >= recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(kSuspendBtnWidth/2.0, recognizer.view.center.y);
                    }
                }else{
                    //左下
                    if (recognizer.view.center.x  >= susScreenH - recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, susScreenH - kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(kSuspendBtnWidth/2.0, recognizer.view.center.y);
                    }
                }
            }else{
                if (recognizer.view.center.y <= susScreenH/2.0) {
                    //右上
                    if (susScreenW - recognizer.view.center.x  >= recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(susScreenW - kSuspendBtnWidth/2.0, recognizer.view.center.y);
                    }
                }else{
                    //右下
                    if (susScreenW - recognizer.view.center.x  >= susScreenH - recognizer.view.center.y) {
                        stopPoint = CGPointMake(recognizer.view.center.x, susScreenH - kSuspendBtnWidth/2.0);
                    }else{
                        stopPoint = CGPointMake(susScreenW - kSuspendBtnWidth/2.0,recognizer.view.center.y);
                    }
                }
            }

            if (stopPoint.x - kSuspendBtnWidth/2.0 <= 0) {
                stopPoint = CGPointMake(kSuspendBtnWidth/2.0, stopPoint.y);
            }

            if (stopPoint.x + kSuspendBtnWidth/2.0 >= susScreenW) {
                stopPoint = CGPointMake(susScreenW - kSuspendBtnWidth/2.0, stopPoint.y);
            }

            if (stopPoint.y - kSuspendBtnWidth/2.0 <= 0) {
                stopPoint = CGPointMake(stopPoint.x, kSuspendBtnWidth/2.0);
            }

            if (stopPoint.y + kSuspendBtnWidth/2.0 >= susScreenH) {
                stopPoint = CGPointMake(stopPoint.x, susScreenH - kSuspendBtnWidth/2.0);
            }

            [UIView animateWithDuration:0.5 animations:^{
                recognizer.view.center = stopPoint;
            }];
        }
            break;

        default:
            break;
    }

    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}

Usage

可直接使用demo裏面的類文件SuspendButtonViewController
直接集繼承該類文件,重寫下面兩個方法即可:


- (void)suspendBtnClicked:(id)sender;
- (void)configSuspendButton;

記得要寫[super configSuspendButton];

截圖如下


屏幕截圖


github下載地址:

更多細節詳見demo

發佈了26 篇原創文章 · 獲贊 12 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章