美文网首页
Swift3仿iPhone小白点吸附控件

Swift3仿iPhone小白点吸附控件

作者: T92 | 来源:发表于2017-07-21 11:10 被阅读60次

    支持拖拽,点击,静止一段时间会有一定透明度,GitHub地址:https://github.com/developerZGJ/ZGSuctionControl

    效果图

    像小白点这种控件一般来说都需要全局使用,因此我将这个对象创建成一个单例,方便调用并且保证该对象唯一。我这里的控件继承自UIView,给其添加了点击手势和拖拽手势。在拖拽和点击后让其不具有透明度,拖拽完成或者点击后隔4秒会具有透明度。为了防止频繁拖动或点击造成透明度频繁改变,我设置了canChangeAlpha变量进行判断。控件很简单,较为核心的就是判断控件的位置应该在哪里。
    拖拽手势响应方法如下:

    func handlePanGesture(pan:UIPanGestureRecognizer){
            if pan.view == nil{
                return
            }
            switch pan.state {
                
            case .began: self.alpha = 1
            
            case .changed:
                let translation = pan.translation(in: self.superview)
                pan.view?.center = CGPoint(x: lastX + translation.x, y: lastY + translation.y)
            case .ended:
                var stopPoint = CGPoint.init(x: 0, y: kScreenH / 2)
        //可以采用三目运算嵌套,但是影响阅读性,因此还是用if else
                if (pan.view!.center.x < kScreenW / 2.0) {
                    if (pan.view!.center.y <= kScreenH/2.0) {
                        //左上
                        stopPoint = pan.view!.center.x  >= pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: btnWidth/2.0) : CGPoint(x: btnWidth/2.0,y: pan.view!.center.y)
                    }else{
                        //左下
                        stopPoint = pan.view!.center.x  >= kScreenH - pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: kScreenH - btnWidth/2.0) : CGPoint(x:btnWidth/2.0,y: pan.view!.center.y)
                    }
                }else{
                    if (pan.view!.center.y <= kScreenH/2.0) {
                        //右上
                        stopPoint = kScreenW - pan.view!.center.x  >= pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: btnWidth/2.0) : CGPoint(x: kScreenW - btnWidth/2.0,y: pan.view!.center.y)
                    }else{
                        //右下
                        stopPoint = kScreenW - pan.view!.center.x  >= kScreenH - pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: kScreenH - btnWidth/2.0) : CGPoint(x: kScreenW - btnWidth/2.0,y: pan.view!.center.y)
                    }
                }
                
                if (stopPoint.x - btnWidth/2.0 <= 0) {
                    stopPoint = CGPoint(x: btnWidth/2.0,y: stopPoint.y);
                }
                
                if (stopPoint.x + btnWidth/2.0 >= kScreenW) {
                    stopPoint = CGPoint(x: kScreenW - btnWidth/2.0,y: stopPoint.y);
                }
                
                if (stopPoint.y - btnWidth/2.0 <= 0) {
                    stopPoint = CGPoint(x: stopPoint.x,y: btnWidth/2.0);
                }
                
                if (stopPoint.y + btnWidth/2.0 >= kScreenH) {
                    stopPoint = CGPoint(x: stopPoint.x,y: kScreenH - btnWidth/2.0);
                }
                
                lastX = stopPoint.x
                lastY = stopPoint.y
                
                weak var weakSelf = self
                UIView.animate(withDuration: 0.3, animations: { 
                    pan.view!.center = stopPoint
                }, completion: { (finish) in
                    weakSelf?.changeAlpha()
                })
                
            default:
                break
            }
        }
    

    其中lastX和lastY是保存控件最终的中心位置坐标,初始值为控件初始位置的中心坐标。
    封装后的完整代码如下,使用了Snapkit,view.addSubview(CustomerServiceView.shared)或者window?.addSubview(CustomerServiceView.shared)进行调用

    
    import UIKit
    import SnapKit
    
    class CustomerServiceView: UIView {
        
        let kScreenH = UIScreen.main.bounds.height
        let kScreenW = UIScreen.main.bounds.width
        
        public static let shared = CustomerServiceView()
        
        fileprivate var canChangeAlpha = true
        
        let btnWidth = 50.fitScreenWidth()
        let btnHeight = 50.fitScreenHeight()
        
        fileprivate var lastX: CGFloat = 0
        fileprivate var lastY: CGFloat = 0
        
        private override init(frame: CGRect) {
            
            
            let x = UIScreen.main.bounds.width - btnWidth - 5
            let y = UIScreen.main.bounds.height / 2 + 20.fitScreenHeight()
            super.init(frame: CGRect(x: x, y: y, width: btnWidth, height: btnHeight))
            let backImageView = UIImageView()
            addSubview(backImageView)
            //        backImageView.image = UIImage(named: "111")
            backImageView.backgroundColor = UIColor.red
            
            backImageView.snp.remakeConstraints { (make) in
                make.top.right.left.bottom.equalTo(0)
            }
            lastX = center.x
            lastY = center.y
            let panRcognize = UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGesture(pan:)))
            self.addGestureRecognizer(panRcognize)
            let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTapGesture(tap:)))
            self.addGestureRecognizer(tap)
            self.alpha = 0.5
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func handleTapGesture(tap: UITapGestureRecognizer?){
            
            self.alpha = 1
            print("被点击")
            //点击响应事件之后需要调用changeAlpha改变透明度
        }
        
        func changeAlpha(){
            guard canChangeAlpha else {
                return
            }
            weak var weakSelf = self
            weakSelf?.canChangeAlpha = false
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3, execute: {
                UIView.animate(withDuration: 1, animations: {
                    weakSelf?.alpha = 0.6
                    weakSelf?.canChangeAlpha = true
                })
            })
        }
        
        func handlePanGesture(pan:UIPanGestureRecognizer){
            if pan.view == nil{
                return
            }
            switch pan.state {
                
            case .began: self.alpha = 1
                
            case .changed:
                let translation = pan.translation(in: self.superview)
                pan.view?.center = CGPoint(x: lastX + translation.x, y: lastY + translation.y)
            case .ended:
                var stopPoint = CGPoint.init(x: 0, y: kScreenH / 2)
                if (pan.view!.center.x < kScreenW / 2.0) {
                    if (pan.view!.center.y <= kScreenH/2.0) {
                        //左上
                        stopPoint = pan.view!.center.x  >= pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: btnWidth/2.0) : CGPoint(x: btnWidth/2.0,y: pan.view!.center.y)
                    }else{
                        //左下
                        stopPoint = pan.view!.center.x  >= kScreenH - pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: kScreenH - btnWidth/2.0) : CGPoint(x:btnWidth/2.0,y: pan.view!.center.y)
                    }
                }else{
                    if (pan.view!.center.y <= kScreenH/2.0) {
                        //右上
                        stopPoint = kScreenW - pan.view!.center.x  >= pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: btnWidth/2.0) : CGPoint(x: kScreenW - btnWidth/2.0,y: pan.view!.center.y)
                    }else{
                        //右下
                        stopPoint = kScreenW - pan.view!.center.x  >= kScreenH - pan.view!.center.y ? CGPoint(x: pan.view!.center.x,y: kScreenH - btnWidth/2.0) : CGPoint(x: kScreenW - btnWidth/2.0,y: pan.view!.center.y)
                    }
                }
                
                if (stopPoint.x - btnWidth/2.0 <= 0) {
                    stopPoint = CGPoint(x: btnWidth/2.0,y: stopPoint.y)
                }
                
                if (stopPoint.x + btnWidth/2.0 >= kScreenW) {
                    stopPoint = CGPoint(x: kScreenW - btnWidth/2.0,y: stopPoint.y)
                }
                
                if (stopPoint.y - btnWidth/2.0 <= 0) {
                    stopPoint = CGPoint(x: stopPoint.x,y: btnWidth/2.0)
                }
                
                if (stopPoint.y + btnWidth/2.0 >= kScreenH) {
                    stopPoint = CGPoint(x: stopPoint.x,y: kScreenH - btnWidth/2.0)
                }
                
                lastX = stopPoint.x
                lastY = stopPoint.y
                
                weak var weakSelf = self
                UIView.animate(withDuration: 0.3, animations: {
                    pan.view!.center = stopPoint
                }, completion: { (finish) in
                    weakSelf?.changeAlpha()
                })
                
            default:
                break
            }
        }
        
    }
    
    extension Int {
        
        func fitScreenHeight() -> CGFloat {
            let screenHeight = UIScreen.main.bounds.height - 64;
            let height : CGFloat = 667.0 - 64;
            let scale = screenHeight / height ;
            return scale * CGFloat(self);
        }
        
        func fitScreenWidth() -> CGFloat {
            let screenWidth = UIScreen.main.bounds.width;
            let width : CGFloat = 375;
            let scale = screenWidth / width ;
            return scale * CGFloat(self);
        }
        
    }
    
    extension CGFloat {
        
        func fitScreenHeight() -> CGFloat {
            let screenHeight = UIScreen.main.bounds.height - 64;
            let height : CGFloat = 667.0 - 64;
            let scale = screenHeight / height ;
            return scale * CGFloat(self);
        }
        
        func fitScreenWidth() -> CGFloat {
            let screenWidth = UIScreen.main.bounds.height;
            let width : CGFloat = 375;
            let scale = screenWidth / width ;
            return scale * CGFloat(self);
        }
        
    }
    

    相关文章

      网友评论

          本文标题:Swift3仿iPhone小白点吸附控件

          本文链接:https://www.haomeiwen.com/subject/kdvskxtx.html