美文网首页绘制
(Swift)吸边可拖拽视图

(Swift)吸边可拖拽视图

作者: 布呐呐u | 来源:发表于2021-09-23 15:34 被阅读0次

一) 使用场景

  • 多用于活动展示;
  • 控件自定义;
  • 支持点击事件;
  • 支持动画效果;
  • 效果如下;


    ki6jt-zt5b3.gif

二) 使用方法

  • 3行代码即可引入使用;
  • 直接初始化CCDragView视图,添加到父视图上,使用frame方式布局;
 let dragView = CCDragView()
 view.addSubview(dragView)
 // dragView.backgroundColor = .main
 dragView.frame = CGRect(x: kScreenWidth() - 70 , y: kScreenHeight() - 70 - 100 , width: 70, height: 70)

三) 源码分享

//
//  CCDragView.swift
//  HelloSwift
//
//  Created by a51095 on 2021/7/15.
//

// 悬浮可拖动视图
// eg: 使用方法,直接初始化CCDragView视图,添加到父视图上,使用frame方式布局
final class CCDragView: UIView {
    /// 限制间距,默认设置2个单位(预留可点击区域)
    private let limitMargin: CGFloat = 2.0
    
    private var contentView = UIView()
    
    public var didSeletedBlock: os_block_t?
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 反初始化器
    deinit {
        print("CCDragView deinit~")
    }
    
    // MARK: - 初始化器
    init() {
        super.init(frame: .zero)
        setUI()
    }
    
    // MARK: - UI初始化
    private func setUI() {
        // 点击手势
        let clickGesture = UITapGestureRecognizer(target: self, action: #selector(dragViewDidClick))
        // 拖拽手势
        let dragGesture = UIPanGestureRecognizer(target: self, action:#selector(dragViewDidDrag(gesture:)))
        contentView.addGestureRecognizer(clickGesture)
        contentView.addGestureRecognizer(dragGesture)
        addSubview(contentView)
        contentView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
    }
    
    // MARK: - 主动移除悬浮视图并销毁定时器
    public func removeDragView() {
        self.removeFromSuperview()
    }
    
    // MARK: - 展示悬浮按钮
    public func showDragView() {
        UIView.animate(withDuration: 0.25) { self.transform = .identity }
    }
    
    // MARK: - 隐藏悬浮按钮
    public func hiddenDragView() {
        // 右位移距离
        var offSet = self.frame.width + limitMargin
        if self.center.x <= self.superview!.center.x {
            // 左位移距离
            offSet = -(self.frame.width + limitMargin)
        }
        // 位移动画
        UIView.animate(withDuration: 0.25) {
            self.transform = CGAffineTransform(translationX: offSet, y: 0)
        }
    }
    
    // MARK: - dragView点击手势
    @objc private func dragViewDidClick() {
        // 隐藏悬浮按钮
        hiddenDragView()
        didSeletedBlock?()
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.showDragView()
        }
    }
    
    // MARK: - dragView拖拽手势
    @objc private func dragViewDidDrag(gesture: UIPanGestureRecognizer) {
        // 移动状态
        let moveState = gesture.state
        switch moveState {
        case .changed:
            // 移动过程中,获取移动轨迹,重置center坐标点
            let point = gesture.translation(in: self.superview)
            self.center = CGPoint(x: self.center.x + point.x, y: self.center.y + point.y)
            break
        case .ended:
            // 移动结束后,相关逻辑处理,重置center坐标点
            let point = gesture.translation(in: self.superview)
            let newPoint = CGPoint(x: self.center.x + point.x, y: self.center.y + point.y)
            
            // 自动吸边动画
            UIView.animate(withDuration: 0.1) {
                self.center = self.resetPosition(point: newPoint)
            }
            break
        default: break
        }
        // 重置 panGesture
        gesture.setTranslation(.zero, in: self.superview!)
    }
    
    // MARK: - 更新中心点位置
    private func resetPosition(point: CGPoint) -> CGPoint {
        var newPoint = point
        
        // 靠左吸边
        if point.x <= (self.superview!.frame.width / 2) {
            // x轴偏右移2个单位(预留可点击区域)
            newPoint.x = (self.frame.width / 2) + limitMargin
            // y轴偏下移10个单位(预留可点击区域)
            if point.y <= kSafeMarginTop(20).cgf { newPoint.y = kSafeMarginTop(40).cgf }
            // y轴偏上移10个单位(预留可点击区域)
            if point.y >= self.superview!.frame.height - (self.frame.height / 2) - kSafeMarginBottom(20).cgf {
                newPoint.y = self.superview!.frame.height - (self.frame.height / 2) - kSafeMarginBottom(10).cgf
            }
            return newPoint
        }else {
            // x轴偏左移2个单位(预留可点击区域)
            newPoint.x = self.superview!.frame.width - (self.frame.width / 2) - limitMargin
            // y轴偏下移10个单位(预留可点击区域)
            if point.y <= kSafeMarginTop(20).cgf { newPoint.y = kSafeMarginTop(40).cgf }
            // y轴偏上移10个单位(预留可点击区域)
            if point.y >= self.superview!.frame.height - (self.frame.height / 2) - kSafeMarginBottom(20).cgf {
                newPoint.y = self.superview!.frame.height - (self.frame.height / 2) - kSafeMarginBottom(10).cgf
            }
            return newPoint
        }
    }
}

四) 更多组件,传送门

GitHub

相关文章

  • (Swift)吸边可拖拽视图

    一) 使用场景 多用于活动展示; 控件自定义; 支持点击事件; 支持动画效果; 效果如下;ki6jt-zt5b3....

  • MacOS 开发(十六) : 文件拖拽

    文件拖拽的核心是拖拽目标视图 (DragDestinationView),此方法会检测目标是否可拖拽类型,拖拽文件...

  • OC 二级联动

    今天写了个二级联动,并且可以弹出一个可拖拽的视图,允许拖拽标题,拖拽完成自动交换布局,而且标题宽度自动适配,允许标...

  • 集合视图抖动,拖拽

    集合视图抖动拖拽

  • Angular cdk 学习之 drag-drop

    Angualr drag-drop里面的功能能让我们非常方便的处理页面上视图的拖拽(自由拖拽、列表排序拖拽、...

  • 微信小程序拖动组件之movable-view

    movable-view 是一个可移动的视图容器,在页面中可以拖拽滑动。(movable-view必须在 mova...

  • 手势-高仿抖音评论效果

    要求:1.不拖拽视图 自然弹上弹下 2.拖拽视图滑动到一定位置选择回弹或销毁 bgScroll允许多手势 核心思路...

  • 简单:iOS做一个字体选择控件:SliderView

    简单分析一下 一个刻度根视图: 三个手势:①:小圆点的拖拽手势②:整个视图的点击手势 需要注意的:拖拽或者点击结束...

  • AndroidTagView 云标签

    介绍 可自定义的标签视图,支持添加标签,点击,长按弹出删除对话框,以及拖拽排序。 Github 类似控件 andr...

  • 拖拽操作

    应用: 1.拖拽排序2.拖拽上传3.拖拽裁剪 拖拽流程 确定可拖拽的内容-->开始拖拽-->拖拽过程-->结束拖拽...

网友评论

    本文标题:(Swift)吸边可拖拽视图

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