天天看点

【iOS开发】一个简单的拖拽悬浮按钮的实现

【iOS开发】一个简单的拖拽悬浮按钮的实现

直接上图:

【iOS开发】一个简单的拖拽悬浮按钮的实现

实现原理使用UIButton的点击事件和手势来实现

//
//  WMMoveButton.swift
//  moveBtn
//
//  Created by wumeng on 2019/8/22.
//  Copyright © 2019 wumeng. All rights reserved.
//

import UIKit


enum WMAssistiveType {
    case none
    case nearLeft
    case nearRight
    case auto
}

class WMFloatButton: UIButton {
    
    fileprivate var blurVisualEffect: UIVisualEffectView!
    
    var action:((WMFloatButton)->Void)? = nil
    var assistiveType:WMAssistiveType = WMAssistiveType.none
    
    
    override init(frame: CGRect) {
        super.init(frame: frame);
        initViews();
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    //MARK:-
    func initViews() -> Void {
        
        self.isUserInteractionEnabled = true
        self.translatesAutoresizingMaskIntoConstraints = false
        
        
        let longPress = UIPanGestureRecognizer(target: self, action: #selector(WMFloatButton.longPress(_:)))
        longPress.delegate = self as? UIGestureRecognizerDelegate
        self.addGestureRecognizer(longPress)
        
        
        self.addTarget(self, action: #selector(WMFloatButton.buttonTapped(_:)), for: .touchUpInside)
        
 
    }
        
    
    //MARK: - Button Actions Methods
    @objc func buttonTapped(_ sender: UIControl) {
        
        if let unwrappedAction = self.action {
            unwrappedAction(self)
        }
    }
    
    
    var buttonOrigin : CGPoint = CGPoint(x: 0, y: 0)
    @objc func longPress(_ pan: UIPanGestureRecognizer) {
        
        if pan.state == .began {
            print("began")
            buttonOrigin = pan.location(in: self)
            
        }else {
            print("pan status not began")
            let location = pan.location(in: self.superview) // get pan location
            self.frame.origin = CGPoint(x: location.x - buttonOrigin.x, y: location.y - buttonOrigin.y)
            
            if(pan.state == .ended){

                self.updateButtonFrame()
            }
        }
        
    }
    
    /// 更新按钮的位置
    private func updateButtonFrame(){

        let btnY:CGFloat = self.frame.origin.y;
        let screenW = self.superview?.bounds.size.width ?? 100;
        let floatBtnW = self.bounds.size.width;
        let floatBtnH = self.bounds.size.height;
        
        switch self.assistiveType {
        case .auto:
            //自动识别贴边
            if (self.center.x >= screenW/2) {
                
                UIView.animate(withDuration: 0.5) {
                    //按钮靠右自动吸边
                    let btnX = screenW - floatBtnW;
                    self.frame = CGRect(x: btnX, y: btnY, width: floatBtnW, height: floatBtnH);
                }
            }else{
                UIView.animate(withDuration: 0.5) {
                    //按钮靠左吸边
                    let btnX:CGFloat = 0.0;
                    self.frame = CGRect(x: btnX, y: btnY, width: floatBtnW, height: floatBtnH);
                }
            }
            break;
        case .none:
            break;
        case .nearLeft:
            UIView.animate(withDuration: 0.5) {
                //按钮靠左吸边
                let btnX:CGFloat = 0.0;
                self.frame = CGRect(x: btnX, y: btnY, width: floatBtnW, height: floatBtnH);
            }
        case .nearRight:
            UIView.animate(withDuration: 0.5) {
                //按钮靠右自动吸边
                let btnX = screenW - floatBtnW;
                self.frame = CGRect(x: btnX, y: btnY, width: floatBtnW, height: floatBtnH);
            }
        }
        
    }

    /*
     // Only override draw() if you perform custom drawing.
     // An empty implementation adversely affects performance during animation.
     override func draw(_ rect: CGRect) {
     // Drawing code
     }
     */
    
}

           

在UIViewController实现

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let button = WMFloatButton.init();
        button.frame = CGRect.init(x: 0, y: 100, width: 50, height: 50)
        button.backgroundColor = UIColor.gray;
        self.view.addSubview(button)
        button.layer.cornerRadius = CGFloat(30 / 2)
        button.layer.shadowOpacity = 1
        button.layer.shadowRadius = 2
        button.layer.shadowOffset = CGSize(width: 1, height: 1)
        button.layer.shadowColor = UIColor.gray.cgColor
        button.setTitle("+", for: UIControl.State.normal)
        button.setImage(nil, for: UIControl.State.normal)
        button.titleLabel!.font = UIFont(name: "HelveticaNeue-Light", size: 35)
        button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)
        
        button.assistiveType = .auto
        
        //点击事件
        button.action = {(sender) in
            print("click---->",123344)
        }
        
    }
    
   


}
           

简单的实现,要实现更多功能需要自己根据自己的需求添加。